Bagaimana Anda mengindeks ulang array dalam PHP?

157

Saya memiliki larik berikut, yang ingin saya isi ulang sehingga kuncinya terbalik (idealnya dimulai dari 1):

Array saat ini ( edit: array sebenarnya terlihat seperti ini):

Array (

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

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

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

)

Bagaimana seharusnya:

Array (

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

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

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

)
meleyal
sumber
1
Di mana ada sesuatu yang terbalik?
Gumbo
Lihat edit saya ke contoh pertama
meleyal
Dan mengapa Anda perlu indeks elemen pertama menjadi 1? Hanya masalah format atau untuk pemrosesan internal?
Gumbo
Ini akan digunakan sebagai param untuk fungsi untuk mendapatkan segmen url, sesuatu seperti get_url_segment (1) akan mengembalikan misalnya pada halaman ini "pertanyaan"
meleyal

Jawaban:

445

Jika Anda ingin mengindeks ulang mulai dari nol, cukup lakukan hal berikut:

$iZero = array_values($arr);

Jika Anda memerlukannya untuk memulai, maka gunakan yang berikut ini:

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

Berikut adalah halaman manual untuk fungsi yang digunakan:

Andrew Moore
sumber
1
Anda harus menggunakan rentang (0, hitungan ($ arr) - 1) sehingga Anda mendapatkan array yang diindeks nol.
Max Hartshorn
Ini bagus, atau Anda dapat mencoba menggunakan array_unshift ($ arr, '') untuk menambahkan elemen yang diindeks nol, lalu hapus ($ arr [0]) untuk menghapusnya, sehingga memindahkan semua indeks dengan satu. Mungkin lebih cepat daripada array_combine (). Atau tidak :)
Steve Horvath
Perhatikan bahwa array_valuesmengembalikan salinan array. Jadi, jika Anda memiliki referensi ke array maka array_spliceakan lebih baik. Lihat solusi @imagiro.
Nux
Hanya array_values()membuatnya bekerja, jika Anda mulai dengan indeks 0 sepanjang waktu.
kishor10d
55

Inilah cara terbaik :

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

itu kembali

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

dengan melakukan ini

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

kamu mendapatkan ini

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

Penjelasan

array_values() : Mengembalikan nilai array input dan indeks secara numerik.

array_filter(): Memfilter elemen array dengan fungsi yang ditentukan pengguna (UDF Jika tidak ada yang disediakan , semua entri dalam tabel input bernilai FALSE akan dihapus .)

Sandra
sumber
3
Jika Anda tidak peduli tentang pesanan, Anda juga bisa hanya mengurutkan ($ array);
Peter M. Elias
array_filter()tampaknya sama sekali tidak relevan dengan data sampel.
mickmackusa
13

Saya baru tahu Anda juga dapat melakukan

array_splice($ar, 0, 0);

Itu melakukan pengindeksan ulang di tempat, sehingga Anda tidak berakhir dengan salinan array asli.

imagiro
sumber
9

Mengapa mengindeks ulang? Cukup tambahkan 1 ke indeks:

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

Sunting    Setelah pertanyaan diklarifikasi: Anda dapat menggunakan array_valuesuntuk mengatur ulang indeks mulai dari 0. Kemudian Anda dapat menggunakan algoritme di atas jika Anda hanya ingin elemen yang dicetak dimulai pada 1.

Gumbo
sumber
jawaban yang diremehkan untuk pertanyaan ini :)
jminkler
6

Yah, saya ingin berpikir bahwa untuk apa pun tujuan akhir Anda, Anda sebenarnya tidak perlu mengubah array menjadi 1 berbasis sebagai lawan dari 0, tetapi sebaliknya bisa menanganinya pada waktu iterasi seperti yang diposting Gumbo.

Namun , untuk menjawab pertanyaan Anda, fungsi ini harus mengubah array apa pun menjadi versi berbasis 1

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

EDIT

Inilah fungsi yang lebih dapat digunakan kembali / fleksibel, jika Anda menginginkannya

$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 ) );
}
Peter Bailey
sumber
5

Ini akan melakukan apa yang Anda inginkan:

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

?>
Greg
sumber
5

Anda mungkin ingin mempertimbangkan mengapa Anda ingin menggunakan array berbasis 1 sama sekali. Array berbasis nol (saat menggunakan array non-asosiatif) cukup standar, dan jika Anda ingin output ke UI, sebagian besar akan menangani solusi dengan hanya meningkatkan integer setelah output ke UI.

Pikirkan tentang konsistensi — baik dalam aplikasi Anda dan dalam kode yang Anda gunakan — ketika memikirkan pengindeks 1 berbasis untuk array.

Michael Trausch
sumber
2
Ini secara langsung berkorelasi dengan pemisahan antara lapisan bisnis dan lapisan presentasi. Jika Anda memodifikasi kode dalam logika Anda untuk mengakomodasi presentasi, Anda melakukan hal-hal buruk. Misalnya, jika Anda melakukan ini untuk pengontrol, tiba-tiba pengontrol Anda terkait dengan penampil tampilan tertentu, bukan menyiapkan data untuk penampil tampilan apa pun yang mungkin digunakan (php, json, xml, rss, dll.)
Tres
5

Solusi yang lebih elegan:

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

Ionuţ Pleşca
sumber
6
Anda menyebut ini elegan?
Julian
5

Anda dapat mengindeks ulang array sehingga array baru dimulai dengan indeks 1 seperti ini;

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

Output dari di atas adalah;

Array
(
    [2] => red
    [1] => green
    [0] => blue
)
Array
(
    [1] => red
    [2] => green
    [3] => blue
)
Nigel Alderton
sumber
Anda tidak harus menggunakannya di array_valuessini. Lihat jawaban saya.
Hujan
4

Mirip dengan @monowerker, saya perlu mengindeks ulang array menggunakan kunci objek ...

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

Ini menghasilkan:

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
        )
)
Nick
sumber
3
$tmp = array();
foreach (array_values($array) as $key => $value) {
    $tmp[$key+1] = $value;
}
$array = $tmp;
Tom Haigh
sumber
3

Jika Anda tidak mencoba menyusun ulang array, Anda cukup melakukan:

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

The array_reverse sangat cepat dan akan menata ulang saat membalikkan. Orang lain sudah lama menunjukkan ini pada saya. Jadi saya tidak bisa mengambil kredit untuk datang dengan itu. Tetapi sangat sederhana dan cepat.

Menandai
sumber
2

Mirip dengan kontribusi Nick, saya datang ke solusi yang sama untuk mengindeks ulang array, tetapi sedikit meningkatkan fungsi sejak dari PHP versi 5.4, itu tidak berfungsi karena meneruskan variabel dengan referensi. Contoh fungsi pengindeksan kembali adalah seperti ini menggunakan usepenutupan kata kunci:

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

Inilah implementasi saya sendiri. Kunci dalam array input akan dinomori ulang dengan penambahan kunci mulai dari $ 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);
}
Mustapha Hadid
sumber
1

Cukup lakukan ini:

<?php

array_push($array, '');
$array = array_reverse($array);
array_shift($array);
Roham Rafii
sumber
1

Anda dapat dengan mudah melakukannya setelah menggunakan fungsi array_values ​​() dan array_filter () bersama-sama untuk menghapus elemen array kosong dan pengindeksan kembali dari array dalam PHP.

fungsi array_filter () Fungsi PHP array_filter () menghapus elemen atau nilai array kosong dari array di PHP. Ini juga akan menghapus nilai kosong, nol, salah, 0 (nol).

function array_values ​​() Fungsi PHP array_values ​​() mengembalikan array yang berisi semua nilai array. Array yang dikembalikan akan memiliki kunci numerik, mulai dari 0 dan meningkat sebesar 1.

Hapus Elemen Array Kosong dan Reindex

Pertama mari kita lihat output array $ stack:

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

Keluaran:

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

Dalam output di atas kami ingin menghapus nilai kosong, nol, 0 (nol) dan kemudian memasukkan kembali elemen array. Sekarang kita akan menggunakan fungsi array_values ​​() dan array_filter () bersama-sama seperti dalam contoh di bawah ini:

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

Keluaran:

Array
(
    [0] => PHP
    [1] => HTML
    [2] => CSS
    [3] => JavaScript
)
Bintang
sumber
array_filter()tampaknya sama sekali tidak relevan dengan data sampel OP.
mickmackusa
1

Penghapusan duplikat dan indeks ulang array:

<?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);
?>
Sam T
sumber
array_filter()tampaknya sama sekali tidak relevan dengan data sampel OP.
mickmackusa
1

Cara tercepat yang bisa saya pikirkan

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

Dan jika Anda hanya ingin mengindeks ulang array (mulai dari nol) dan Anda memiliki PHP +7.3 Anda dapat melakukannya dengan cara ini

array_unshift($arr);

Saya percaya array_unshiftlebih baik daripada array_valuesyang pertama tidak membuat salinan array.

Hujan
sumber
0

Rasanya semua array_combine()jawaban menyalin semua "kesalahan" yang sama (panggilan yang tidak perlu array_values()).

array_combine() mengabaikan kunci kedua parameter yang diterimanya.

Kode: ( Demo )

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

Keluaran:

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,
  ),
)
mickmackusa
sumber
0

Penyortiran hanyalah semacam () , pengindeksan ulang tampak agak konyol tetapi jika diperlukan ini akan melakukannya. Meski tidak di tempat. Gunakan array_walk () jika Anda akan melakukan ini di banyak tempat, cukup gunakan loop for-key-value jika ini adalah operasi satu kali.

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

?>
Monowerker
sumber
-10

Jika OK untuk membuat array baru, ini dia:

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

Jika Anda membutuhkan pembalikan di tempat, Anda harus menjalankan mundur sehingga Anda tidak menginjak indeks yang Anda butuhkan:

for ( $k = count($array) ; $k-- > 0 ; )
    $result[ $k+1 ] = $result[ $k ];
unset( $array[0] );   // remove the "zero" element
Jason Cohen
sumber
20
Setiap jawaban untuk masalah ini seharusnya tidak memerlukan perulangan. Bagian penting dari jawabannya adalah menggunakan array_values()untuk mendapatkan array berbasis 0 dan kemudian membuat beberapa penyesuaian untuk hasil itu jika array berbasis 1 benar- benar diperlukan.
Grantwparks