将PHP数组中的值移到数组开头

21

我有一个类似于以下PHP数组:

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

我想把黄色移动到索引0。我该怎么做?

编辑:我的问题是如何将任何一个元素移动到开头?我该如何将绿色或蓝色移动到索引0?这个问题不仅仅关于将最后一个元素移动到开头。


你能说一下你想让数组最终看起来像什么吗?它可以是 黄色,红色,绿色,蓝色黄色,蓝色,绿色,红色黄色,绿色,蓝色,红色,每个都有不同的处理过程。此外,它是否总是要从末尾移到前面,还是可以是任意位置移到前面? - Reese Moore
12个回答

30

对我来说,这似乎是最简单的方法。您可以将任何位置移到开头,而不仅仅是最后一个(在此示例中,它将蓝色移动到开头)。

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

$movecolour = $colours[2];
unset($colours[2]);
array_unshift($colours, $movecolour);

4
这个线程中唯一正确的答案没有奇怪的副作用,也没有漏掉处理空值的情况。我真的很想把它顶得更高或者把其他答案顶得更低,但不幸的是这是不可能的。 - griffin
1
@griffin 同意! 我正在搜索这个问题,只是为了确认我的实现方式,但我对其他答案的复杂性感到惊讶,幸运的是,我的实现方式与SharpC的一致! - Lennon
我一直在寻找更好的方法来完成这个任务,但看起来这可能是最好的方式。在生产代码中,如果我不知道键名,唯一的区别就是使用array_search查找所需值的键名,然后对该键名进行unset/unshift操作。 - James Alday

15

可能是最直接的方法。

array_unshift( $arr, array_pop( $arr ) );

编辑

根据您的评论“我如何从数组中取任何一个下标并将其移动到开头”,我上面的回答并没有完全满足该要求 - 它仅通过将最后一个元素移动到0索引位置来实现。

然而,这个函数可以满足该要求。

/**
 * 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;
}

而且,在使用时

$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

2
@Reese Moore Cups的代码并不能回答我所理解的问题。 - ceejayoz
@ceejayoz:Cups的代码完全符合问题要求,因为问题除了要求“yellow”在数组顶部之外,没有规定结束条件。将其反转就可以做到这一点。 - Reese Moore
2
我的问题是如何从数组中取出任意一个下标并将其移动到开头? - Jarred
8/10 会在生产中使用。 - jtavares
-1 第一个答案并没有完全回答问题,第二个答案在某些情况下是不正确的,例如 $a = array( NULL, NULL, NULL ) 仍然是一个有效的数组,但 isset($a[0]) === false。而且过于复杂。unset($arr[$k]); array_unshift($arr, $val); - 简单、易懂、正确。可以使用例如 array_values 进行其他重新排序。 - griffin
显示剩余4条评论

9

这个函数可以让你将一个元素移动到数组中任意位置,同时保持数组其他元素不变:

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;
}

希望使用方法很明显,因此这样做:

$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)
);

将输出这个:

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 只适用于整数索引,过于复杂(仍然没有足够的参数检查等)。+1 实现了 OP 没有要求的额外功能 ;) - griffin

5
你想把其中一个元素移动到开头。例如:
$old = array(
'key1' =>'value1', 
'key2' =>'value2', 
'key3' =>'value3', 
'key4' =>'value4');

您希望将key3移动到开头。

$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 因为答案正确(不过在键上你仍然应该使用严格比较),-1 因为代码效率低下。另外再加一分,因为它甚至可以保留键,而 array_shift 无法做到这一点(如果要求保留键,你的代码可能会是最有效的)。 - griffin

5

这与SharpC的答案非常相似,但考虑到您可能不知道值在数组中的位置(即键)或是否已设置。如果颜色未设置或已经是数组中的第一个元素,则“if”检查将跳过它。

$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);
}

3
如果仍有人在寻找答案,这里提供一种替代方案。
$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]);

那就是这样了。 :)

2

编辑:

这是基于Peter Bailey的答案的更新,但代码对我来说太过于函数/内存密集型,因此下面只是简单地交换$from和$to值。此方法不会导致所讨论的数组被调整大小,它只是在其中交换了两个值。

第二次编辑:我根据评论中提到的添加了一些更多的参数检查。

function moveValueByIndex( array $array, $from=null, $to=null )
{
  // There is no array, or there are either none or a single entry
  if ( null === $array || count($array) < 2 )
  {
    // Nothing to do, just return what we had
    return $array;
  }

  if ( null === $from )
  {
    $from = count( $array ) - 1;
  }

  if ( null === $to )
  {
    $to = 0;
  }

  if ( $to == $from )
  {
    return $array;
  }

  if ( !array_key_exists($from, $array) )
  {
    throw new Exception( "Key $from does not exist in supplied array." );
  }

  $value = $array[$from];
  $array[$from] = $array[$to];
  $array[$to] = $value;

  return $array;
}

如果我应该在Peter的帖子中添加评论,那么请原谅我..只是太长了,不能全部内联显示 :/


抱歉,这段内容与IT技术无关。请提供更多相关信息以便我为您提供更准确的翻译。


哎呀,我忘记删除那些参数的默认值了!谢谢,我还添加了一个 $from == $to 等等。 - James
-1 表示不能正确处理数组中的 NULL 元素,同时也没有必要进行数组键检查(这只会使得只有以 0 为起始索引的整数键才能正常工作 - 但是为什么要这样做呢?) - griffin
@griffin 这个方法为什么不能处理 NULL 元素? - James
如果元素为NULL,则使用消息“偏移$from不存在”抛出异常。请参见http://www.php.net/manual/en/function.isset.php“...并且不为NULL。”- 使用http://www.php.net/manual/en/function.array-key-exists.php会更加正确。 - griffin
@griffin 谢谢,已更新答案并删除了现在不需要的键检查,以替换为array_key_exists()。 - James

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

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

原帖所要求的内容已经更新,不再适用。 - James

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

$b = array_reverse( $a );

如果你的问题是如何让最后一个变成第一个。

2
这会将整个数组反转,而不仅仅是将“yellow”移动到开头。 - ceejayoz
@ceejayoz:提问者除了指出“yellow”在开头之外,从未明确说明数组的最终状态。 - Reese Moore
我假设如果他没有提到对数组其余部分的更改,那么他是希望仅将“yellow”更改位置。 - ceejayoz
@ceejayoz:那为什么要将其他所有东西向下移动,而不是简单地将其与“red”交换,这将对数组的更改更少。 - Reese Moore
将其与红色交换会改变数组其余部分的顺序。 - ceejayoz
很好,因为OP提出了一个含糊不清的问题而被打了分 - 我甚至还特意解释了我的观点!当然它会反转整个数组,提示就在函数名中。 - Cups

0
你可以这样做:
$array = array("red", "green", "blue", "yellow");
$last = array_pop($array);
array_unshift($array, $last);
print_r($array);

结果:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接