Làm thế nào để bạn reindex một mảng trong PHP?


156

Tôi có mảng sau, tôi muốn reindex để các khóa được đảo ngược (lý tưởng bắt đầu từ 1):

Mảng hiện tại ( chỉnh sửa: mảng thực sự trông như thế này):

Array (

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

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

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

)

Nó nên như thế nào:

Array (

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

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

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

)

1
Trường hợp có một cái gì đó đảo ngược?
Gumbo

Xem bản chỉnh sửa của tôi với ví dụ đầu tiên
meleyal

Và tại sao bạn cần chỉ số của phần tử đầu tiên là 1? Chỉ là một vấn đề định dạng hoặc để xử lý nội bộ?
Gumbo

Nó sẽ được sử dụng như một tham số cho một hàm để có được một đoạn url, một cái gì đó như get_url_seribution (1) sẽ trả về, ví dụ như trên trang này "câu hỏi"
meleyal

Câu trả lời:


444

Nếu bạn muốn lập chỉ mục lại bắt đầu từ 0, chỉ cần làm như sau:

$iZero = array_values($arr);

Nếu bạn cần nó để bắt đầu tại một, sau đó sử dụng như sau:

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

Dưới đây là các trang hướng dẫn cho các chức năng được sử dụng:


1
Bạn nên sử dụng phạm vi (0, đếm ($ mảng) - 1) để bạn có được một mảng không có chỉ mục.
Max Hartshorn

Thật tuyệt vời, thay vào đó, bạn có thể thử sử dụng Array_unshift ($ Array, '') để thêm phần tử có chỉ mục bằng 0, sau đó bỏ đặt ($ Array [0]) để xóa nó, do đó di chuyển tất cả các chỉ mục lên một. Nó có thể nhanh hơn mảng_combine (). Hoặc không :)
Steve Horvath

Lưu ý rằng array_valuestrả về một bản sao của mảng. Vì vậy, nếu bạn có tài liệu tham khảo đến mảng thì array_splicesẽ tốt hơn. Xem giải pháp @imagiro.
Nux

Chỉ array_values()làm cho nó hoạt động, nếu bạn bắt đầu với chỉ số 0 mọi lúc.
kishor10d

55

Đây là cách tốt nhất :

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

trả lại

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

bằng cách này

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

bạn nhận được điều này

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

Giải trình

array_values() : Trả về các giá trị của mảng đầu vào và lập chỉ mục bằng số.

array_filter(): Lọc các phần tử của một mảng bằng hàm do người dùng xác định (UDF Nếu không được cung cấp , tất cả các mục trong bảng đầu vào có giá trị FALSE sẽ bị xóa .)


3
Nếu bạn không quan tâm đến thứ tự, bạn cũng có thể sắp xếp ($ mảng);
Peter M. Elias

array_filter()dường như hoàn toàn không liên quan đến dữ liệu mẫu.
mickmackusa

13

Tôi chỉ phát hiện ra bạn cũng có thể làm một

array_splice($ar, 0, 0);

Điều đó thực hiện việc lập chỉ mục lại tại chỗ, vì vậy bạn không kết thúc với một bản sao của mảng ban đầu.


9

Tại sao reindexing? Chỉ cần thêm 1 vào chỉ mục:

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

Chỉnh sửa    Sau khi câu hỏi đã được làm rõ: Bạn có thể sử dụng array_valuesđể đặt lại chỉ mục bắt đầu từ 0. Sau đó, bạn có thể sử dụng thuật toán ở trên nếu bạn chỉ muốn các phần tử được in bắt đầu từ 1.


câu trả lời bị đánh giá thấp cho câu hỏi này :)
jminkler

6

Chà, tôi muốn nghĩ rằng dù mục tiêu cuối cùng của bạn là gì, bạn thực sự sẽ không cần phải sửa đổi mảng thành 1 dựa trên trái ngược với dựa trên 0, nhưng thay vào đó có thể xử lý nó tại thời điểm lặp như Gumbo đã đăng.

Tuy nhiên , để trả lời câu hỏi của bạn, hàm này nên chuyển đổi bất kỳ mảng nào thành phiên bản dựa trên 1

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

BIÊN TẬP

Đây là một chức năng linh hoạt / tái sử dụng hơn, nếu bạn muốn nó

$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

Điều này sẽ làm những gì bạn muốn:

<?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

Bạn có thể muốn xem xét lý do tại sao bạn muốn sử dụng một mảng dựa trên 1. Các mảng dựa trên zero (khi sử dụng các mảng không liên kết) là tiêu chuẩn khá và nếu bạn muốn xuất ra UI, hầu hết sẽ xử lý giải pháp bằng cách chỉ tăng số nguyên khi xuất ra UI.

Hãy suy nghĩ về tính nhất quán của cả hai trong ứng dụng của bạn và trong mã mà bạn làm việc với tinh thần khi nghĩ về các bộ chỉ mục dựa trên 1 cho các mảng.


2
Điều này liên quan trực tiếp đến sự tách biệt giữa lớp kinh doanh và lớp trình bày. Nếu bạn đang sửa đổi mã trong logic của mình để phù hợp với việc trình bày, bạn đang làm điều xấu. Ví dụ: nếu bạn đã làm điều này cho bộ điều khiển, đột nhiên bộ điều khiển của bạn được gắn với trình kết xuất chế độ xem cụ thể thay vì chuẩn bị dữ liệu cho bất kỳ trình kết xuất chế độ xem nào mà nó có thể sử dụng (php, json, xml, rss, v.v.)
Tres

5

Một giải pháp thanh lịch hơn:

$list = array_combine(range(1, count($list)), array_values($list));


6
Bạn gọi đây là thanh lịch?
Julian

5

Bạn có thể reindex một mảng để mảng mới bắt đầu với chỉ số 1 như thế này;

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

Đầu ra từ trên là;

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

Bạn không cần phải sử dụng array_valuesở đây. Xem câu trả lời của tôi.
Mưa

4

Tương tự như @monowerker, tôi cần reindex một mảng bằng khóa của đối tượng ...

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

Điều này dẫn đến:

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

Nếu bạn không cố gắng sắp xếp lại mảng, bạn có thể thực hiện:

$ mảng = mảng numverse ($ mảng);
$ mảng = mảng numverse ($ mảng);

Mảng thông tin rất nhanh và nó sắp xếp lại khi nó đảo ngược. Một người khác cho tôi thấy điều này từ lâu. Vì vậy, tôi không thể lấy tín dụng để đến với nó. Nhưng nó rất đơn giản và nhanh chóng.


2

Tương tự như sự đóng góp của Nick, tôi đã đi đến cùng một giải pháp cho việc giới thiệu lại một mảng, nhưng đã tăng cường chức năng một chút kể từ phiên bản PHP 5.4, nó không hoạt động vì chuyển các biến bằng tham chiếu. Ví dụ chức năng reindexing là như thế này bằng cách sử dụng useđóng từ khóa:

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

1

Đây là thực hiện của riêng tôi. Các khóa trong mảng đầu vào sẽ được đánh số lại bằng các khóa tăng dần bắt đầu từ $ 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

Đơn giản chỉ cần làm điều này:

<?php

array_push($array, '');
$array = array_reverse($array);
array_shift($array);

1

Bạn có thể dễ dàng thực hiện nó sau khi sử dụng hàm Array_values ​​() và Array_filter () để loại bỏ các phần tử mảng trống và reindex khỏi một mảng trong PHP.

Hàm Array_filter () Hàm Array_filter () loại bỏ các phần tử hoặc giá trị mảng trống khỏi một mảng trong PHP. Điều này cũng sẽ loại bỏ các giá trị trống, null, false, 0 (zero).

Hàm Array_values ​​() Hàm Array_values ​​() trả về một mảng chứa tất cả các giá trị của một mảng. Mảng được trả về sẽ có các phím số, bắt đầu từ 0 và tăng thêm 1.

Loại bỏ các thành phần mảng rỗng và Reindex

Trước tiên, hãy xem đầu ra mảng $ stack:

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

Đầu ra:

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

Trong đầu ra ở trên, chúng tôi muốn loại bỏ các giá trị trống, null, 0 (không) và sau đó reindex các phần tử mảng. Bây giờ chúng ta sẽ sử dụng hàm Array_values ​​() và Array_filter () như trong ví dụ dưới đây:

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

Đầu ra:

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

array_filter()dường như hoàn toàn không liên quan đến dữ liệu mẫu của OP.
mickmackusa

1

Loại bỏ trùng lặp và reindex một mảng:

<?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()dường như hoàn toàn không liên quan đến dữ liệu mẫu của OP.
mickmackusa

1

Cách nhanh nhất tôi có thể nghĩ đến

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

Và nếu bạn chỉ muốn reindex mảng (bắt đầu từ 0) và bạn có PHP +7.3, bạn có thể làm theo cách này

array_unshift($arr);

Tôi tin array_unshiftlà tốt hơn so array_valuesvới trước đây không tạo ra một bản sao của mảng.


0

Cảm giác như tất cả các array_combine()câu trả lời đều sao chép cùng một "lỗi" (cách gọi không cần thiết array_values()).

array_combine() bỏ qua các khóa của cả hai tham số mà nó nhận được.

Mã: ( Bản trình diễn )

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

Đầu ra:

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

Sắp xếp chỉ là một sắp xếp () , reindexing có vẻ hơi ngớ ngẩn nhưng nếu cần nó sẽ làm điều đó. Mặc dù không tại chỗ. Sử dụng mảng_walk () nếu bạn sẽ thực hiện việc này trong một loạt các địa điểm, chỉ cần sử dụng vòng lặp for-key-value nếu đây là hoạt động một lần.

<?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

Nếu nó ổn để tạo một mảng mới thì đây là:

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

Nếu bạn cần đảo ngược tại chỗ, bạn cần chạy ngược lại để không dậm chân vào các chỉ mục mà bạn cần:

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

20
Bất kỳ câu trả lời cho vấn đề này không cần một vòng lặp. Phần chính của câu trả lời là sử dụng array_values()để có được một mảng dựa trên 0 và sau đó thực hiện một số điều chỉnh cho kết quả đó nếu một mảng dựa trên 1 là thực sự cần thiết.
Grantwparks
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.