21

I have a PHP array similar to this:

0 => "red",
1 => "green",
2 => "blue",
3 => "yellow"

I want to move yellow to index 0.

How do I move any one of these elements to the beginning? How would I move green to index 0, or blue to index 0? This question is not exclusively about moving the last element to the beginning.

5
  • 1
    Could you say what you want the array to look like afterwards? It could be yellow, red, green, blue, yellow, blue, green, red, yellow, green, blue, red and each of these would have different processes. Furthermore does it always have to be the end to the front or is it an arbitrary position to the front? Commented Nov 8, 2010 at 17:58
  • See also Move an array element to a new index in PHP if looking to move an element identified by its position to a new position. Commented Mar 9 at 7:43
  • How do you know which value to move? Are you targeting yellow by its known key? By its position? By the first occurring element with the value yellow? What if yellow occurs more than once? Are we swapping the first and last values or bumping all other values by one? Commented Mar 9 at 10:23
  • @mickmackusa I think that would be a good duplicate target. You could probably re-vote on this to dupehammer it once the existing votes expire. Commented Mar 10 at 14:07
  • @TylerH I cannot be sure about that. If this question is about swapping yellow with red, okay it is a clearer duplicate page with an full minimal reproducible example. If this question is about moving yellow to a new position and affecting all other elements in its path to the new position, then it is not a suitable duplicate. This question is too ambiguous -- this is why I've voted as Unclear. Commented Mar 11 at 0:16

11 Answers 11

31

This seems like the simplest way to me. You can move any position to the beginning, not just the last (in this example it moves blue to the beginning).

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

$movecolour = $colours[2];
unset($colours[2]);
array_unshift($colours, $movecolour);
Sign up to request clarification or add additional context in comments.

Comments

14

This function does satisfy that request

/**
 * Move array element by index.  Only works with zero-based,
 * contiguously-indexed arrays
 *
 * @param array $array
 * @param integer $from Use NULL when you want to move the last element
 * @param integer $to   New index for moved element. Use NULL to push
 * 
 * @throws Exception
 * 
 * @return array Newly re-ordered array
 */
function moveValueByIndex( array $array, $from=null, $to=null )
{
  if ( null === $from )
  {
    $from = count( $array ) - 1;
  }

  if ( !isset( $array[$from] ) )
  {
    throw new Exception( "Offset $from does not exist" );
  }

  if ( array_keys( $array ) != range( 0, count( $array ) - 1 ) )
  {
    throw new Exception( "Invalid array keys" );
  }

  $value = $array[$from];
  unset( $array[$from] );

  if ( null === $to )
  {
    array_push( $array, $value );
  } else {
    $tail = array_splice( $array, $to );
    array_push( $array, $value );
    $array = array_merge( $array, $tail );
  }

  return $array;
}

And, in usage

$arr = array( 'red', 'green', 'blue', 'yellow' );

echo implode( ',', $arr ); // red,green,blue,yellow

// Move 'blue' to the beginning
$arr = moveValueByIndex( $arr, 2, 0 );

echo implode( ',', $arr ); // blue,red,green,yellow

8 Comments

@Sarfraz: technically Cups's is more compact (he just initialized the array) and still fits with the question requirements.
@Reese Moore Cups's code doesn't answer the question as I interpreted it.
@ceejayoz: Cups's code does exactly what the question asks as the question does not stipulate the end condition other than that yellow had to be at the top of the array. Reversing it does just that.
My question is how can I take any one subscript from the array and move it to the beginning?
-1 First answer doesn't completely answer, and second one is just not correct in all cases, e.g. $a = array( NULL, NULL, NULL ) is still a valid array, but isset($a[0]) === false. Also overly complicated. unset($arr[$k]); array_unshift($arr, $val); - simple, easy, correct. Additional reordering can be done using e.g. array_values.
|
9

This function will allow you to move an element to an arbitrary position within the array, while leaving the rest of the array untouched:

function array_reorder($array, $oldIndex, $newIndex) {
    array_splice(
        $array,
        $newIndex,
        count($array),
        array_merge(
            array_splice($array, $oldIndex, 1),
            array_slice($array, $newIndex, count($array))
        )
    );
    return $array;
}

Hopefully the usage is fairly obvious, so this:

$array = array('red','green','blue','yellow',);

var_dump(
    array_reorder($array, 3, 0),
    array_reorder($array, 0, 3),
    array_reorder($array, 1, 3),
    array_reorder($array, 2, 0)
);

Will output this:

array(4) {
  [0]=>
  string(6) "yellow"
  [1]=>
  string(3) "red"
  [2]=>
  string(5) "green"
  [3]=>
  string(4) "blue"
}
array(4) {
  [0]=>
  string(5) "green"
  [1]=>
  string(4) "blue"
  [2]=>
  string(6) "yellow"
  [3]=>
  string(3) "red"
}
array(4) {
  [0]=>
  string(3) "red"
  [1]=>
  string(4) "blue"
  [2]=>
  string(6) "yellow"
  [3]=>
  string(5) "green"
}
array(4) {
  [0]=>
  string(4) "blue"
  [1]=>
  string(3) "red"
  [2]=>
  string(5) "green"
  [3]=>
  string(6) "yellow"
}

1 Comment

-1 Only works for integer indexes and is overly complicated (and still doesn't do enough checking of parameters etc.). +1 for achieving additional functionality the OP didn't even ask for ;)
5

You want to move one of the elements to the beginning. Let's say

$old = array(
'key1' =>'value1', 
'key2' =>'value2', 
'key3' =>'value3', 
'key4' =>'value4');

And you want to move key3 to the beginnig.

$new = array();
$new['key3'] = $old['key3']; // This is the first item of array $new
foreach($old as $key => $value) // This will continue adding $old values but key3
{
if($key != 'key3')$new[$key]=$value;
}

1 Comment

+1 For being correct (you should still have used strict comparison on the key), -1 for being inefficient and slow (the code, I mean). Still another +1 because it even works for keeping keys, which array_shift can't (if this would've been asked for, your code would unfortunately probably the most efficient).
4

This is very similar to SharpC's answer but accounts for the fact that you may not know where the value is in the array (it's key) or if it is even set. The 'if' check will skip over it if the color isn't set or if it's already the first element in the array.

$color = 'yellow';
$color_array = array("red", "green", "blue", "yellow");

$key = array_search($color, $color_array);

if ($key > 0) {
   unset($color_array[$key]);
   array_unshift($color_array, $color);
}

Comments

3

Here is an alternate way.

$colors = array("red","green","blue","yellow");
$color_to_move = ["yellow"];
$colors_wo_yellow = array_diff($colors, $color_to_move);// This will give an array without "yellow"
//Now add "yellow" as 1st element to $
array_unshift($colors_wo_yellow,$color_to_move[0]);

Comments

0
$array = array(
  'red',
  'green',
  'blue',
  'yellow',
);

$last = array_pop($array);
array_unshift($array, $last);

1 Comment

No longer does what the original post has been updated to ask for.
0
$a = array('red','green', 'blue','yellow');

$b = array_reverse( $a );

If your question is how to make the last become the first.

5 Comments

This'll reverse the entire array, though, not just move 'yellow' to the beginning.
@ceejayoz: The questioner never specified the state of the array at the end other than that yellow was at the beginning.
I assume if he didn't mention any changes to the rest of the array, he intended for only 'yellow' to change location.
@ceejayoz: then why shift everything else down, why not simply swap it with red, that would involve less change to the array.
Swapping it with red changes the order of the rest of the array.
0

You can do like this:

$array = array("red", "green", "blue", "yellow");
$last = array_pop($array);
array_unshift($array, $last);
print_r($array);

Result:

Array ( [0] => yellow [1] => red [2] => green [3] => blue ) 

Comments

0

If you aren't always planning on bringing the very last object to the beginning of the array, this would be the most simplistic way to go about it...

$array = array('red','green','blue','yellow');
unset($array[array_search($searchValue, $array)]);
array_unshift($array, $searchValue);

1 Comment

-1 doesn't handle return value of array_search, and if it's only intended for values known to be in the array, it still doesn't handle doubled values, and is needlessly to complex (why search if you know which you want to be moved?)
0

PHP: move any element to the first or any position:

$sourceArray = array(
    0 => "red",
    1 => "green",
    2 => "blue",
    3 => "yellow"
);
// set new order
$orderArray = array(
    3 => '',
    1 => '',
);
$result = array_replace($orderArray, $sourceArray);
print_r($result);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.