如何在PHP中为数组重新索引?


157

我有以下数组,我想对其重新索引,以使键反向(理想情况下从1开始):

当前数组(编辑:该数组实际上看起来像这样):

Array (

[2] => Object
    (
        [title] => Section
        [linked] => 1
    )

[1] => Object
    (
        [title] => Sub-Section
        [linked] => 1
    )

[0] => Object
    (
        [title] => Sub-Sub-Section
        [linked] => 
    )

)

应该如何:

Array (

[1] => Object
    (
        [title] => Section
        [linked] => 1
    )

[2] => Object
    (
        [title] => Sub-Section
        [linked] => 1
    )

[3] => Object
    (
        [title] => Sub-Sub-Section
        [linked] => 
    )

)

1
哪里有什么逆转?
Gumbo

请参阅我对第一个示例的编辑
meleyal

而且为什么您需要第一个元素的索引为1?只是格式问题还是内部处理?
Gumbo

它将用作获取URL段的函数的参数,例如get_url_segment(1)之类的内容将在此页面上返回“问题”
meleyal

Answers:


445

如果要重新索引从零开始,只需执行以下操作:

$iZero = array_values($arr);

如果您需要从头开始,请使用以下命令:

$iOne = array_combine(range(1, count($arr)), array_values($arr));

以下是所用功能的手册页:


1
您应该使用range(0,count($ arr)-1),以便获得零索引数组。
Max Hartshorn

很好,或者您可以尝试使用array_unshift($ arr,'')添加零索引元素,然后使用unset($ arr [0])删除它,从而将所有索引上移一个。它可能比array_combine()更快。是否:)
Steve Horvath '18

请注意,array_values返回数组的副本。因此,如果您对数组有引用,array_splice那就更好了。请参阅@imagiro解决方案。
Nux

array_values()当始终从索引0开始时,才使其起作用。
kishor10d

55

这是最好的方法

# Array
$array = array('tomato', '', 'apple', 'melon', 'cherry', '', '', 'banana');

返回

Array
(
    [0] => tomato
    [1] => 
    [2] => apple
    [3] => melon
    [4] => cherry
    [5] => 
    [6] => 
    [7] => banana
)

通过做这个

$array = array_values(array_filter($array));

你得到这个

Array
(
    [0] => tomato
    [1] => apple
    [2] => melon
    [3] => cherry
    [4] => banana
)

说明

array_values() :返回输入数组的值并以数字形式索引。

array_filter():使用用户定义的函数过滤数组的元素(UDF 如果未提供则将删除输入表中所有值为FALSE的条目。)


3
如果您不关心顺序,也可以只排序($ array);
彼得·埃里亚斯

array_filter()似乎与样本数据完全无关。
mickmackusa

13

我才发现你也可以

array_splice($ar, 0, 0);

这样就可以进行重新索引,因此您不会得到原始数组的副本。


9

为什么要重新编制索引?只需将1添加到索引:

foreach ($array as $key => $val) {
    echo $key + 1, '<br>';
}

编辑    在问题明确之后:您可以使用array_values重置从0开始的索引。然后,如果您只希望打印的元素从1开始,则可以使用上面的算法。


这个问题的答案被低估了:)
jminkler

6

好吧,我想认为无论您的最终目标是什么,您实际上都不需要将数组修改为基于1而不是基于0的数组,而是可以像Gumbo发布那样在迭代时进行处理。

但是,要回答您的问题,此函数应将任何数组转换为基于1的版本

function convertToOneBased( $arr )
{
    return array_combine( range( 1, count( $arr ) ), array_values( $arr ) );
}

编辑

如果需要,这是一个更可重用/灵活的功能

$arr = array( 'a', 'b', 'c' );

echo '<pre>';
print_r( reIndexArray( $arr ) );
print_r( reIndexArray( $arr, 1 ) );
print_r( reIndexArray( $arr, 2 ) );
print_r( reIndexArray( $arr, 10 ) );
print_r( reIndexArray( $arr, -10 ) );
echo '</pre>';

function reIndexArray( $arr, $startAt=0 )
{
    return ( 0 == $startAt )
        ? array_values( $arr )
        : array_combine( range( $startAt, count( $arr ) + ( $startAt - 1 ) ), array_values( $arr ) );
}

5

这将满足您的要求:

<?php

$array = array(2 => 'a', 1 => 'b', 0 => 'c');

array_unshift($array, false); // Add to the start of the array
$array = array_values($array); // Re-number

// Remove the first index so we start at 1
$array = array_slice($array, 1, count($array), true);

print_r($array); // Array ( [1] => a [2] => b [3] => c ) 

?>

5

您可能要考虑为什么完全要使用基于1的数组。从零开始的数组(使用非关联数组时)是非常标准的,如果要输出到UI,大多数将通过在输出到UI时增加整数来处理该解决方案。

当考虑数组的基于1的索引器时,请考虑应用程序和使用的代码中的一致性。


2
这与业务层和表示层之间的分离直接相关。如果您正在修改逻辑中的代码以适应演示,那么您所做的事情就很糟糕。例如,如果您对控制器执行此操作,则突然将您的控制器绑定到特定的视图渲染器,而不是为其可能使用的任何视图渲染器准备数据(php,json,xml,rss等)
Tres


5

您可以为数组重新索引,以便新数组从索引1开始,如下所示;

$arr = array(
  '2' => 'red',
  '1' => 'green',
  '0' => 'blue',
);

$arr1 = array_values($arr);   // Reindex the array starting from 0.
array_unshift($arr1, '');     // Prepend a dummy element to the start of the array.
unset($arr1[0]);              // Kill the dummy element.

print_r($arr);
print_r($arr1);

上面的输出是:

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

您不必array_values在这里使用。看我的答案。
下雨

4

类似于@monowerker,我需要使用对象的键为数组重新索引...

$new = array();
$old = array(
  (object)array('id' => 123),
  (object)array('id' => 456),
  (object)array('id' => 789),
);
print_r($old);

array_walk($old, function($item, $key, &$reindexed_array) {
  $reindexed_array[$item->id] = $item;
}, &$new);

print_r($new);

结果是:

Array
(
    [0] => stdClass Object
        (
            [id] => 123
        )
    [1] => stdClass Object
        (
            [id] => 456
        )
    [2] => stdClass Object
        (
            [id] => 789
        )
)
Array
(
    [123] => stdClass Object
        (
            [id] => 123
        )
    [456] => stdClass Object
        (
            [id] => 456
        )
    [789] => stdClass Object
        (
            [id] => 789
        )
)

3
$tmp = array();
foreach (array_values($array) as $key => $value) {
    $tmp[$key+1] = $value;
}
$array = $tmp;

3

如果您不打算对数组重新排序,则可以执行以下操作:

$ array = array_reverse($ array);
$ array = array_reverse($ array);

array_reverse速度非常快,并且在反向时会重新排序。很久以前有人给我看过这个。因此,我无法为自己提出建议。但这是非常简单和快速的。


2

与Nick的贡献相似,我使用了相同的解决方案来重新索引数组,但是由于PHP 5.4版本中的功能有所增强,因此该功能由于通过引用传递变量而无法使用。然后,使用use关键字闭包的示例重新索引功能如下:

function indexArrayByElement($array, $element)
{
    $arrayReindexed = [];
    array_walk(
        $array,
        function ($item, $key) use (&$arrayReindexed, $element) {
            $arrayReindexed[$item[$element]] = $item;
        }
    );
    return $arrayReindexed;
}

1

这是我自己的实现。输入数组中的键将使用从$ start_index开始的递增键重新编号。

function array_reindex($array, $start_index)
{
    $array = array_values($array);
    $zeros_array = array_fill(0, $start_index, null);
    return array_slice(array_merge($zeros_array, $array), $start_index, null, true);
}


1

在结合使用array_values()和array_filter()函数以从PHP中的数组中删除空数组元素并重新索引之后,您可以轻松地做到这一点。

array_filter()函数 PHP array_filter()函数从PHP中的数组中删除空数组元素或值。这还将删除空白,空,假,0(零)值。

array_values()函数 PHP array_values()函数返回一个包含数组所有值的数组。返回的数组将具有数字键,从0开始并以1递增。

删除空数组元素并重新索引

首先让我们看一下$ stack数组的输出:

<?php
  $stack = array("PHP", "HTML", "CSS", "", "JavaScript", null, 0);
  print_r($stack);
?>

输出:

Array
(
    [0] => PHP
    [1] => HTML
    [2] => CSS
    [3] => 
    [4] => JavaScript
    [5] => 
    [6] => 0
)

在上面的输出中,我们要删除空白,空,0(零)值,然后重新索引数组元素。现在,我们将一起使用array_values()和array_filter()函数,如下例所示:

<?php
  $stack = array("PHP", "HTML", "CSS", "", "JavaScript", null, 0);
  print_r(array_values(array_filter($stack)));
?>

输出:

Array
(
    [0] => PHP
    [1] => HTML
    [2] => CSS
    [3] => JavaScript
)

array_filter()似乎与OP的样本数据完全无关。
mickmackusa

1

复制删除并重新索引数组:

<?php  
   $oldArray = array('0'=>'php','1'=>'java','2'=>'','3'=>'asp','4'=>'','5'=>'mysql');
   //duplicate removal
   $fillteredArray = array_filter($oldArray);
   //reindexing actually happens  here
   $newArray = array_merge($filteredArray);
   print_r($newArray);
?>

array_filter()似乎与OP的样本数据完全无关。
mickmackusa

1

我能想到的最快方法

array_unshift($arr, null);
unset($arr[0]);
print_r($arr);

而且,如果您只想重新索引数组(从零开始)并且拥有PHP +7.3,则可以使用这种方法

array_unshift($arr);

我相信array_unshiftarray_values以前更好,因为前者不创建数组的副本。


0

感觉所有array_combine()答案都在复制相同的“错误”(的不必要调用array_values())。

array_combine() 忽略它收到的两个参数的键。

代码:(演示

$array = [
    2 => (object)['title' => 'Section', 'linked' => 1],
    1 => (object)['title' => 'Sub-Section', 'linked' => 1],
    0 => (object)['title' => 'Sub-Sub-Section', 'linked' => null]
];

var_export(array_combine(range(1, count($array)), $array));

输出:

array (
  1 => 
  (object) array(
     'title' => 'Section',
     'linked' => 1,
  ),
  2 => 
  (object) array(
     'title' => 'Sub-Section',
     'linked' => 1,
  ),
  3 => 
  (object) array(
     'title' => 'Sub-Sub-Section',
     'linked' => NULL,
  ),
)

0

排序只是一个sort(),重新索引似乎有点愚蠢,但是如果需要的话,可以这样做。虽然不到位。如果要在很多地方使用array_walk(),则如果使用一次,则使用for-key-value循环。

<?php

function reindex(&$item, $key, &$reindexedarr) {
    $reindexedarr[$key+1] = $item;
}

$arr = Array (2 => 'c', 1 => 'b', 0 => 'a');

sort($arr);
$newarr = Array();
array_walk($arr, reindex, &$newarr);
$arr = $newarr;
print_r($arr); // Array ( [1] => a [2] => b [3] => c )

?>

-10

如果可以制作一个新数组,那就是这样:

$result = array();
foreach ( $array as $key => $val )
    $result[ $key+1 ] = $val;

如果需要就地反转,则需要向后运行,这样就不会踩到所需的索引:

for ( $k = count($array) ; $k-- > 0 ; )
    $result[ $k+1 ] = $result[ $k ];
unset( $array[0] );   // remove the "zero" element

20
对这个问题的任何答案都不需要循环。答案的关键部分是array_values()用来获取从0开始的数组,然后如果确实需要从1开始的数组,则对该结果进行一些调整。
grantwparks
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.