Come reindicizzi un array in PHP?


157

Ho il seguente array, che vorrei reindicizzare in modo che le chiavi siano invertite (idealmente a partire da 1):

Array corrente ( modifica: l'array in realtà si presenta così):

Array (

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

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

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

)

Come dovrebbe essere:

Array (

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

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

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

)

1
Dov'è qualcosa invertito?
Gumbo,

Vedi la mia modifica al primo esempio
meleyal,

E perché hai bisogno che l'indice del primo elemento sia 1? Solo una questione di formato o per l'elaborazione interna?
Gumbo,

Verrà utilizzato come parametro per una funzione per ottenere il segmento a url, qualcosa come get_url_segment (1) restituirebbe ad esempio in questa pagina "domande"
meleyal

Risposte:


445

Se vuoi reindicizzare iniziando da zero, procedi semplicemente nel seguente modo:

$iZero = array_values($arr);

Se ne hai bisogno per iniziare da uno, quindi utilizzare quanto segue:

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

Ecco le pagine di manuale per le funzioni utilizzate:


1
Dovresti usare range (0, count ($ arr) - 1) in modo da ottenere un array con indice zero.
Max Hartshorn,

È fantastico, in alternativa puoi provare a usare array_unshift ($ arr, '') per aggiungere un elemento a zero, quindi disinserire ($ arr [0]) per rimuoverlo, spostando così tutti gli indici di uno. Forse è più veloce di array_combine (). O no :)
Steve Horvath,

Si noti che array_valuesrestituisce una copia dell'array. Quindi, se si hanno riferimenti all'array, array_splicesarebbe meglio. Vedi la soluzione @imagiro.
Nux,

Fallo array_values()funzionare solo se inizi sempre con l'indice 0.
kishor10d,

55

Ecco il modo migliore :

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

che ritorna

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

facendo questo

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

hai capito

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

Spiegazione

array_values() : Restituisce i valori dell'array di input e gli indici numericamente.

array_filter(): Filtra gli elementi di un array con una funzione definita dall'utente (UDF Se non viene fornito nessuno , tutte le voci nella tabella di input valutate FALSE verranno eliminate .)


3
Se non ti interessa l'ordine, puoi anche ordinare ($ array);
Peter M. Elias,

array_filter()sembra completamente irrilevante per i dati di esempio.
Mickmackusa

13

Ho appena scoperto che puoi anche fare un

array_splice($ar, 0, 0);

Ciò esegue la reindicizzazione sul posto, quindi non si finisce con una copia dell'array originale.


9

Perché reindicizzare? Basta aggiungere 1 all'indice:

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

Modifica    Dopo che la domanda è stata chiarita: è possibile utilizzare array_valuesper ripristinare l'indice a partire da 0. Quindi è possibile utilizzare l'algoritmo sopra se si desidera solo che gli elementi stampati inizino da 1.


risposta sottovalutata a questa domanda :)
jminkler

6

Bene, vorrei pensare che per qualunque sia il tuo obiettivo finale, non avresti effettivamente bisogno di modificare l'array in modo che sia basato su 1 anziché su 0, ma potresti invece gestirlo al momento dell'iterazione come pubblicato da Gumbo.

Tuttavia , per rispondere alla tua domanda, questa funzione dovrebbe convertire qualsiasi array in una versione basata su 1

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

MODIFICARE

Ecco una funzione più riutilizzabile / flessibile, se lo desideri

$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

Questo farà quello che vuoi:

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

È possibile considerare il motivo per cui si desidera utilizzare un array basato su 1. Gli array a base zero (quando si utilizzano array non associativi) sono piuttosto standard e, se si desidera eseguire l'output in un'interfaccia utente, la maggior parte gestirà la soluzione semplicemente aumentando il numero intero all'output nell'interfaccia utente.

Pensa alla coerenza, sia nella tua applicazione che nel codice con cui lavori, quando pensi agli indicizzatori basati su 1 per array.


2
Ciò è direttamente correlato alla separazione tra il livello aziendale e il livello di presentazione. Se stai modificando il codice nella tua logica per adattarlo alla presentazione, stai facendo cose cattive. Ad esempio, se lo hai fatto per un controller, improvvisamente il controller è legato a uno specifico renderer di visualizzazione piuttosto che prepara i dati per qualsiasi renderizzatore di visualizzazione che può utilizzare (php, json, xml, rss, ecc.)
Tres,

5

Una soluzione più elegante:

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


6
Lo chiami elegante?
Giuliano,

5

È possibile reindicizzare un array in modo che il nuovo array inizi con un indice di 1 come questo;

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

L'output di cui sopra è;

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

Non devi usare array_valuesqui. Vedi la mia risposta
Pioggia

4

Simile a @monowerker, avevo bisogno di reindicizzare un array usando la chiave di un oggetto ...

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

Ciò ha comportato:

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

Se non stai cercando di riordinare l'array, puoi semplicemente fare:

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

Array_reverse è molto veloce e si riordina mentre si inverte. Qualcun altro me lo ha mostrato molto tempo fa. Quindi non posso prendermi il merito per averlo inventato. Ma è molto semplice e veloce.


2

Simile al contributo di Nick, sono arrivato alla stessa soluzione per reindicizzare un array, ma ho migliorato un po 'la funzione dalla versione 5.4 di PHP, non funziona a causa del passaggio di variabili per riferimento. La funzione di reindicizzazione di esempio è quindi simile usando la usechiusura di parole chiave:

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

1

Ecco la mia implementazione. Le chiavi nella matrice di input verranno rinumerate con chiavi incrementali a partire da $ 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

Basta fare questo:

<?php

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

1

Puoi farlo facilmente dopo aver usato insieme la funzione array_values ​​() e array_filter () per rimuovere elementi di array vuoti e reindicizzare da un array in PHP.

funzione array_filter () La funzione array_filter () di PHP rimuove elementi o valori di array vuoti da un array in PHP. Questo rimuoverà anche i valori vuoti, null, false, 0 (zero).

funzione array_values ​​() La funzione array_values ​​() di PHP restituisce un array contenente tutti i valori di un array. L'array restituito avrà tasti numerici, che iniziano da 0 e aumentano di 1.

Rimuovere gli elementi dell'array vuoti e Reindex

Per prima cosa vediamo l'output dell'array $ stack:

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

Produzione:

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

Nell'output sopra vogliamo rimuovere valori vuoti, null, 0 (zero) e quindi reindicizzare gli elementi dell'array. Ora useremo array_values ​​() e array_filter () insieme come nell'esempio seguente:

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

Produzione:

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

array_filter()sembra completamente irrilevante per i dati di esempio del PO.
Mickmackusa

1

Rimozione duplicata e reindicizzazione di un 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);
?>

array_filter()sembra completamente irrilevante per i dati di esempio del PO.
mickmackusa

1

Il modo più veloce che mi viene in mente

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

E se vuoi solo reindicizzare l'array (inizia da zero) e hai PHP +7.3 puoi farlo in questo modo

array_unshift($arr);

Credo che array_unshiftsia meglio di array_valuescome il primo non crea una copia dell'array.


0

Sembra che tutte le array_combine()risposte stiano tutte copiando lo stesso "errore" (il richiamo inutile di array_values()).

array_combine() ignora le chiavi di entrambi i parametri che riceve.

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

Produzione:

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

L'ordinamento è solo un ordinamento () , la reindicizzazione sembra un po 'sciocca, ma se è necessario, lo farà. Anche se non sul posto. Usa array_walk () se lo farai in molti punti, usa un ciclo for-key-value se si tratta di un'operazione una tantum.

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

Se è OK per creare un nuovo array è questo:

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

Se è necessario eseguire l'inversione sul posto, è necessario correre all'indietro in modo da non calpestare gli indici necessari:

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

20
Qualsiasi risposta a questo problema non dovrebbe richiedere un ciclo. La parte chiave della risposta sta usando array_values()per ottenere un array basato su 0 e quindi apportare alcune modifiche a quel risultato se un array basato su 1 è realmente necessario.
grantwparks,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.