21

My array:

$data = array('two' => 2, 'one' => 1, 'three' => 3);

Now, with when I iterate the array, the first value that will come up will probably be

$data['two'] // = 2 @ index[0]

right?

What if I want to move the $data[1] to the position of $data[0] ?

To rephrase:

How do I make the array look like this (so that 'one' comes up at $data[0])

$data = array('one' => 1, 'two' => 2, 'three' => 3

Why do I need this?

I use code igniter, the table->generate built-in function takes an assoc array and creates a table but offers no method of arranging the columns. This is why I would like to move the columns in the source array.

4
  • Possible duplicate of Sort an Array by keys based on another Array? Commented Mar 2, 2016 at 22:08
  • @iautomation The question did not make any mention of using a second array to control the order of the first. They asked for a solution to control the order of the keys after the array has been created. Using another array MAY be one possible solution, but it should not be a limiting factor in finding solutions for this question. Commented Oct 19, 2017 at 12:26
  • why don't you want to sort? Commented Dec 1, 2021 at 14:04
  • It looks like your actual task doesn't resemble your sample data. Maybe something more realistic would allow volunteers to provide something that will actually work with you CodeIgniter project. Do you already know all of the column and the desired column orders? You aren't just moving one column, right? Commented Feb 1 at 5:27

5 Answers 5

24

Two possible solutions (without using array_splice):

1) Create a new array with the new order of the keys.

$new_keys = array('one', 'two', 'three');
$new_data = array();
foreach ($new_keys as $key) {
    $new_data[$key] = $data[$key];
}
$data = $new_data;

2) Move the element one upfront, remove it from $data and copy the rest of the array.

function rearrangeData($data) {
    $result['one'] = $data['one'];
    unset($data['one']);
    return array_merge($result, $data);
}    
$data = rearrangeData($data);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! One suggestion to solution 1: If you have more keys as $new_keys have, it will strip the others completely. Maybe there should be a fallback and let the others "unsorted".
7

Take a look at daniele centamore's comment on PHP's array_splice() function, where he provides a couple of functions for moving the elements in an non-associative array.

<?php

// $input  (Array) - the array containing the element
// $index (int) - the index of the element you need to move

function moveUp($input,$index) {
      $new_array = $input;

       if((count($new_array)>$index) && ($index>0)){
                 array_splice($new_array, $index-1, 0, $input[$index]);
                 array_splice($new_array, $index+1, 1);
             } 

       return $new_array;
}

function moveDown($input,$index) {
       $new_array = $input;

       if(count($new_array)>$index) {
                 array_splice($new_array, $index+2, 0, $input[$index]);
                 array_splice($new_array, $index, 1);
             } 

       return $new_array;
}  

$input = array("red", "green", "blue", "yellow");

$newinput = moveUp($input, 2);
// $newinput is array("red", "blue", "green", "yellow")

$input = moveDown($newinput, 1);
// $input is array("red", "green", "blue", "yellow")

?>

1 Comment

That doesn't really answer the question. Daniele's example is not for associative arrays
2

See ksort and uksort.

Here's a working example:

<?php

$data = array('two' => 2, 'one' => 1, 'three' => 3);
print_r($data);
ksort($data);
echo "ksort:\n";
print_r($data);
uksort($data,'cmp');
echo "uksort:\n";
print_r($data);
function cmp($a, $b)
{
    $num=' one two three four five six seven eight nine ten';
    $ai = stripos($num,$a);
    $bi = stripos($num,$b);
    if ($ai>0 && $bi>0) {
        return ($ai > $bi) ? 1 : -1;
    }
    return strcasecmp($a, $b);
}

Output:

Array
(
    [two] => 2
    [one] => 1
    [three] => 3
)
ksort:
Array
(
    [one] => 1
    [three] => 3
    [two] => 2
)
uksort:
Array
(
    [one] => 1
    [two] => 2
    [three] => 3
)

Run this: http://codepad.org/yAK1b1IP

Comments

0

PHP has 13 functions for sorting arrays, by key, by value, by user-defined functions where you can specify that "one" comes before "two". There's also array_shift, array_unshift, array_push and array_pop for moving things onto or off the front or end of the array. You can build a whole new array from the existing one.

4 Comments

I know, these functions are great. However, notice how it says 'Not sort' in the title. Also, I couldn't find the function array_move_index('one',0);
Rearranging a set of items is sorting. Just because your ordering is not lexicographic or numeric doesn't mean arranging arrays in that order isn't sorting. That's the very meaning of the word.
Exacly, you should use usort and write a simple closure.
This vague hint of an answer should have been posted as a comment under the question. It makes very little attempt to resolve the actual asked question. If the question is too vague, then vote to close instead of answering.
-1

I think, you should use asort function:

$data = array('two' => 2, 'one' => 1, 'three' => 3);

$dataOrdered = $data;
asort($dataOrdered);

Run this code

2 Comments

This does not sort by key, it sorts by value! See here: codepad.org/wUAsV5hr
Question specifically requested a non-sort solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.