PHP'de bir diziyi nasıl yeniden endekslersiniz?


157

Anahtarları tersine (ideal olarak 1'den başlayarak) böylece ben reindex istiyorum aşağıdaki dizi var:

Geçerli dizi ( değiştir: dizi aslında şöyle görünür):

Array (

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

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

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

)

Nasıl olmalı:

Array (

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

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

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

)

1
Tersine çevrilmiş bir şey nerede?
Gumbo

İlk örneğe yaptığım düzenlemeye bakın
meleyal

Ve neden ilk elemanın indeksinin 1 olması gerekiyor? Sadece biçim meselesi mi yoksa dahili işleme mi?
Gumbo

Bir url segmentini almak için bir işlev için bir param olarak kullanılacaktır, get_url_segment (1) gibi bir şey bu sayfada "sorular" olarak
dönecektir

Yanıtlar:


445

Sıfırdan başlayarak yeniden endekslemek istiyorsanız, aşağıdakileri yapmanız yeterlidir:

$iZero = array_values($arr);

Birinden başlamak için ihtiyacınız varsa, aşağıdakileri kullanın:

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

Kullanılan işlevler için kılavuz sayfaları şunlardır:


1
Sıfır indeksli bir dizi elde etmek için aralık (0, sayım ($ arr) - 1) kullanmalısınız.
Max Hartshorn

Alternatif olarak, sıfır dizinli bir öğe eklemek için array_unshift ($ arr, '') kullanmayı deneyebilir, ardından kaldırmak için ($ arr [0]) ayarını kaldırarak tüm dizinleri birer birer yukarı taşıyabilirsiniz. Dizi_kombininden () daha hızlı olabilir. Or not :)
Steve Horvath

array_valuesDizinin bir kopyasını döndüren unutmayın . Diziye referanslarınız varsa, o array_splicezaman daha iyi olurdu. @İmagiro çözümüne bakınız.
Nux

Sadece array_values()indeks 0 ile her zaman başlarsanız çalışmasını sağlayın.
kishor10d

55

İşte en iyi yol :

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

bu geri döner

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

bunu yaparak

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

bunu aldın

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

açıklama

array_values() : Girdi dizisinin ve dizinlerin değerlerini sayısal olarak döndürür.

array_filter(): Kullanıcı tanımlı bir işleve sahip bir dizinin öğelerini filtreler (UDF Hiçbiri sağlanmazsa , FALSE değerine sahip giriş tablosundaki tüm girdiler silinir .)


3
Eğer sipariş umurumda değil de sadece ($ dizi) sıralayabilirsiniz;
Peter M. Elias

array_filter()örnek verilerle tamamen alakasız görünüyor.
mickmackusa

13

Az önce bir de

array_splice($ar, 0, 0);

Bu, yeniden indekslemeyi yerinde yapar, böylece orijinal dizinin bir kopyasıyla sonuçlanmazsınız.


9

Neden yeniden endeksleme? Dizine 1 ekleyin:

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

Düzenle    Soru açıklığa kavuşturulduktan sonra: array_values0'dan başlayarak dizini sıfırlamak için düğmesini kullanabilirsiniz. Ardından, yazdırılan öğelerin 1'den başlamasını istiyorsanız yukarıdaki algoritmayı kullanabilirsiniz.


bu soruya yetersiz cevap :)
jminkler

6

Son hedefiniz ne olursa olsun, diziyi 0 tabanlı yerine 1 tabanlı olacak şekilde değiştirmek zorunda kalmayacağınızı düşünmek istiyorum, ancak bunun yerine Gumbo'nun yayınladığı gibi yineleme zamanında işleyebilir.

Ancak , sorunuzu cevaplamak için bu işlev herhangi bir diziyi 1 tabanlı bir sürüme dönüştürmelidir

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

DÜZENLE

İsterseniz daha yeniden kullanılabilir / esnek bir işlev var

$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

Bu istediğinizi yapar:

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

Neden 1 tabanlı bir dizi kullanmak istediğinizi düşünmek isteyebilirsiniz. Sıfır tabanlı diziler (ilişkilendirilebilir olmayan diziler kullanılırken) oldukça standarttır ve bir kullanıcı arayüzüne çıktı almak istiyorsanız, çoğu kullanıcı arayüzü çıktısı üzerine tamsayıyı artırarak çözümü ele alır.

Diziler için 1 tabanlı dizinleyicileri düşünürken hem uygulamanızda hem de birlikte çalıştığınız kodda tutarlılığı düşünün.


2
Bu, iş katmanı ile sunum katmanı arasındaki ayrımla doğrudan ilişkilidir. Sunumu gerçekleştirmek için mantığınızdaki kodu değiştiriyorsanız, kötü şeyler yapıyorsunuz demektir. Örneğin, bunu bir denetleyici için yaptıysanız, aniden denetleyiciniz kullanabileceği görünüm oluşturucu için veri hazırlamak yerine belirli bir görünüm oluşturucuya bağlanır (php, json, xml, rss, vb.)
Tres

5

Daha zarif bir çözüm:

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


6
Buna zarif mi diyorsun?
Julian

5

Bir diziyi yeniden dizine ekleyerek yeni dizinin böyle bir 1 diziniyle başlamasını sağlayabilirsiniz;

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

Yukarıdakilerden çıktı;

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

array_valuesBurada kullanmak zorunda değilsiniz . Cevabımı gör.
Yağmur

4

@Monowerker'a benzer şekilde, bir nesnenin anahtarını kullanarak bir diziyi yeniden endekslemem gerekiyordu ...

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

Bunun sonucunda:

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

Diziyi yeniden sıralamaya çalışmıyorsanız, şunları yapabilirsiniz:

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

Array_reverse çok hızlıdır ve tersine dönerken yeniden sıralar. Birisi bana bunu uzun zaman önce gösterdi. Bu yüzden geldiği için kredi alamıyorum. Ama çok basit ve hızlı.


2

Nick'in katkısına benzer şekilde, bir diziyi yeniden endekslemek için aynı çözüme geldim, ancak PHP sürüm 5.4'ten beri işlevi biraz geliştirdim, değişkenleri referans olarak geçirdiği için çalışmıyor. Örnek reindexing işlevi, useanahtar kelime kapatma özelliğini kullanarak şu şekildedir :

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

1

İşte kendi uygulamam. Giriş dizisindeki anahtarlar, $ start_index 'den başlayarak artan anahtarlarla yeniden numaralandırılacaktır.

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

Sadece bunu yapın:

<?php

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

1

PHP'de bir diziden boş dizi öğelerini kaldırmak ve dizini yeniden oluşturmak için array_values ​​() ve array_filter () işlevini birlikte kullandıktan sonra kolayca yapabilirsiniz.

array_filter () işlevi PHP array_filter () işlevi, PHP'deki bir diziden boş dizi öğelerini veya değerleri kaldırır. Bu ayrıca boş, boş, yanlış, 0 (sıfır) değerlerini de kaldıracaktır.

array_values ​​() işlevi PHP array_values ​​() işlevi, bir dizinin tüm değerlerini içeren bir dizi döndürür. Döndürülen dizi, 0'dan başlayıp 1 oranında artan sayısal tuşlara sahip olacaktır.

Boş Dizi Öğelerini ve Reindex'i Kaldırma

İlk önce $ stack dizi çıktısını görelim:

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

Çıktı:

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

Yukarıdaki çıktıda boş, boş, 0 (sıfır) değerleri kaldırmak ve sonra dizi öğelerini yeniden dizine eklemek istiyoruz. Şimdi array_values ​​() ve array_filter () işlevini aşağıdaki örnekte olduğu gibi birlikte kullanacağız:

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

Çıktı:

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

array_filter()OP'nin örnek verileriyle tamamen alakasız görünüyor.
mickmackusa

1

Yinelenen kaldırma ve diziyi yeniden dizine ekleme:

<?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'nin örnek verileriyle tamamen alakasız görünüyor.
mickmackusa

1

Düşünebildiğim en hızlı yol

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

Ve diziyi yeniden endekslemek istiyorsanız (sıfırdan başlayın) ve PHP +7.3'ünüz varsa bunu bu şekilde yapabilirsiniz

array_unshift($arr);

Önceki dizi bir kopyasını oluşturmaz gibi array_unshiftdaha iyi olduğuna inanıyorum array_values.


0

Tüm array_combine()cevapların hepsi aynı "hatayı" (gereksiz çağrıyı array_values()) kopyalıyor gibi geliyor .

array_combine() aldığı her iki parametrenin anahtarlarını yok sayar.

Kod: ( 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));

Çıktı:

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ıralama sadece bir çeşittir () , yeniden endeksleme biraz aptalca görünür, ancak gerekirse bunu yapar. Yerinde olmasa da. Bunu bir dizi yerde yapacaksanız array_walk () öğesini kullanın , bu bir kerelik bir işlemse for-anahtar-değer döngüsü kullanı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

Yeni bir dizi oluşturmakta sorun yoksa:

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

Yerinde ters çevirmeye ihtiyacınız varsa, ihtiyacınız olan dizinlerde durmamanız için geriye doğru koşmanız gerekir:

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

20
Bu soruna herhangi bir yanıtın bir döngüye ihtiyacı yoktur. Cevabın temel kısmı array_values()0 tabanlı bir dizi almak ve daha sonra 1 tabanlı bir dizi gerçekten gerekliyse bu sonuç için bazı ayarlamalar yapmak için kullanmaktır .
grantwparks
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.