Accesso a un array associativo tramite indice intero in PHP


92

Voglio impostare il valore di un array associativo utilizzando l'indice dell'array della coppia chiave / valore. Per esempio:

$my_arr = array( "bling" => "some bling", "bling2" => "lots O bling" );
$my_arr[1] = "not so much bling";  // Would change the value with key bling2.

Come è possibile farlo senza utilizzare la stringa chiave?

Risposte:


188

Usa array_keys .

$keys = array_keys($my_arr);
$my_arr[$keys[1]] = "not so much bling";

Spero che questo ti aiuti.


4
Come nota a margine, perché gli sviluppatori PHP dovrebbero creare un modo così non intuitivo di accedere a un array?
Marty

3
@Marty questo ha meno a che fare con il modo in cui gli sviluppatori PHP lo hanno implementato, ma più con la tua incomprensione su come funzionano gli array. Tecnicamente, quanto sopra utilizza ancora il nome associativo. Non esiste alcuna correlazione tra le chiavi di indice numeriche e associative.
Gordon

2
Crei un array associativo perché ciò che stai cercando è più importante della sua posizione nell'array. Penso che questo sia un buon punto. Supponiamo di avere un array con i nomi degli studenti come chiavi e gli indirizzi come valori. Puoi raggiungere l'indirizzo di uno studente tramite il suo nome. La posizione dell'array è irrilevante. E puoi ordinare l'array per name of the student.
Donovan

@ Gordon tecnicamente è vero. Ma il programmatore fornisce un numero, non una stringa. Penso che questo sia il significato di without using a key string.
Donovan

2
@ Albert stai mappando questo numero alla stringa di chiavi appropriata. Ciò non significa che array[1] === $array['foo']però. L'array potrebbe ancora contenere un altro valore in $array[1]. Nota che non sto dicendo che la tua soluzione è sbagliata. È il presupposto dell'OP.
Gordon

27

Non esiste alcuna correlazione tra le chiavi di indice numeriche e associative.

Quando dici di voler impostare il valore di un array associativo usando l'indice dell'array della chiave / valore , allora devi usare la chiave data, l'impostazione $array[1]non è la stessa dell'impostazione $array['foo'].

Considera questo array

print_r( array('foo', 'foo' => 'bar', 'baz', 'some' => 'value') );

Questo darà

Array
(
    [0] => foo
    [foo] => bar
    [1] => baz
    [some] => value
)

Il foo è il secondo elemento dell'array. Questo è l' offset , ma non ha nulla a che fare con l'indice 1. Come puoi vedere, in quell'array sopra, l'indice 1 è associato baz. È sbagliato presumere che, proprio perché fooè la prima chiave associativa, abbia qualcosa a che fare con la chiave numerica reale 1. Proprio come somenon è correlato a 2.

Allo stesso modo, per un array misto come mostrato sopra, la soluzione array_keyssuggerita altrove su questo sito non funzionerà, perché

print_r( array_keys(array('foo', 'foo' => 'bar', 'baz', 'some' => 'value')) );

darà

Array
(
    [0] => 0
    [1] => foo
    [2] => 1
    [3] => some
)

Quindi quando lo fai $array[$keys[1]]lo stai facendo davvero $array['foo']. Ma se volessi accedere al secondo valore associativo in quell'array ( 'some'), non puoi farlo $array[$keys[2]]perché verrebbe valutato $array[1]e questo baz.

L'offset di un elemento non è completamente correlato alla sua chiave o valore

print_r(
    array(
        100    => 'foo',
        'foo'  => 'bar',
        50     => 'baz',
        'some' => 'value'
    )
);

significa davvero

Array
( //key       value     offset/position
    [100]  => foo       // 0
    [foo]  => bar       // 1
    [50]   => baz       // 2
    [some] => value     // 3
)

il che significa che l'elemento all'offset 0 è foo sebbene la chiave sia 100. Se vuoi estrarre elementi da un array per offset, devi usare

$third = array_splice($array, 2, 1);
echo $third[0]; // baz

Questo creerebbe un array che contiene solo l'elemento nella terza posizione.

Oppure potresti usare un file ArrayIterator. Le ArrayIteratorimplementa Seekableun'interfaccia che consente di cercare una posizione specifica / Offset nella matrice e quindi del recupero:

$iterator = new ArrayIterator($array);
$iterator->seek(3);
echo $iterator->current(); // value

Minor nit: "se si desidera accedere al secondo valore associativo in quell'array ('some'), non è possibile eseguire $ array [$ keys [2]] perché sarebbe $ array [1] e questo è baz" Tecnicamente, questo perché tutte le chiavi, comprese quelle numeriche, sono chiavi associative : i 4 valori restituiti da array_keys. Non esiste un'entità come una "chiave non associativa". Se intendevi sottolineare che non puoi restituire la seconda chiave di stringa (assumendo che l'array di chiavi contenga solo stringhe), allora quello che dici è corretto. $stringKeys = array_filter(array_keys($array), "is_string");fornisce le chiavi della stringa.
ToolmakerSteve

17

Mentre array_keys()consente l'accesso all'ennesima chiave, array_valuesti darà l'ennesimo valore.

<?php
$array = [
   0     => 'Zero',
   '1'   => 'One',
   'Two' => 'Two',
];
echo array_values($array)[2];
?>

produrrà "Due".

C'è un vantaggio dell'uno sull'altro? Bene, l'unico minore che posso vedere è il numero di accessi all'array.

Con array_keys()è necessario 3.

  1. Ottieni le chiavi dall'array di dati.
  2. Ottieni l'ennesima chiave dall'elenco delle chiavi.
  3. Ottieni il valore utilizzando l'ennesima chiave dall'array di dati.

Con array_values(), hai solo bisogno di 2.

  1. Ottieni i valori dalla matrice di dati.
  2. Ottieni l'ennesimo valore dall'elenco dei valori.

Ma, d'altra parte, le chiavi sono normalmente più piccole ei dati potrebbero essere enormemente annidati, quindi, a conti fatti, l'uso di array_keys()è probabilmente più sicuro.


3

Se l'array è grande, entrambi array_keyse array_valuessaranno uno spreco poiché assegneranno un nuovo array della stessa dimensione dell'originale, solo per ottenere l' ennesima chiave (o valore).

array_sliceaccetta un offset intero e funziona su array associativi. Puoi usarlo per ottenere (e impostare) l' ennesima chiave in tempo costante.

// This will at most allocate 2 temporary arrays of 1 element each
$key = array_keys(array_slice($array, $n, 1, true))[0];

$array[$key] = $value;

2
Bella soluzione qui!
Daan

1

Prova questo. Funziona per te.

$result= array_values($my_arr); // Array with indexes you need

1
Fai attenzione quando pubblichi su un vecchio thread che ha già diverse risposte e una risposta accettata. Devi spiegare perché la tua nuova risposta è migliore di quelle esistenti.
APC

0

Un'altra possibilità è convertirlo in un normale array:

$ arraybuff = implode ("~~~", $ my_arr);
$ my_arr = explode ("~~~", $ arraybuff);

Dove "~~~" è un delimitatore che non si verificherà nei tuoi dati.

Ora puoi accedere all'array utilizzando indici numerici uguali agli offset.

Se è ancora necessario mantenere il proprio array associativo, è sufficiente assegnarlo a una variabile diversa.


Poiché dovresti sempre e mai considerare, questo delimitatore esatto può essere presente nei tuoi dati, questa idea funziona solo nel 99,9999999%. Esistono diverse soluzioni che funzioneranno al 100%. Inoltre, questo imposta il processore su molto lavoro e spreco di memoria per un semplice accesso all'array.
user426486
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.