Zugriff auf ein assoziatives Array über einen Integer-Index in PHP

92

Ich möchte den Wert eines assoziativen Arrays mithilfe des Array-Index des Schlüssel / Wert-Paares festlegen. Beispielsweise:

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

Wie kann dies erreicht werden, ohne die Schlüsselzeichenfolge zu verwenden?

Marty
quelle

Antworten:

188

Verwenden Sie array_keys .

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

Hoffe das hilft.

Donovan
quelle
4
Nebenbei bemerkt, warum sollten die PHP-Entwickler eine so nicht intuitive Art des Zugriffs auf ein Array erstellen?
Marty
3
@Marty Dies hat weniger damit zu tun, wie PHP-Entwickler es implementiert haben, als vielmehr mit Ihrem Missverständnis, wie Arrays funktionieren. Technisch verwendet das Obige immer noch den assoziativen Namen. Es gibt keine Korrelation zwischen numerischen und assoziativen Indexschlüsseln.
Gordon
2
Sie erstellen ein assoziatives Array, da das, wonach Sie suchen, wichtiger ist als seine Position im Array. Ich denke, das ist ein guter Punkt. Angenommen, Sie haben ein Array mit Schülernamen als Schlüssel und Adressen als Werte. Sie können die Adresse eines Schülers anhand seines Namens erreichen. Die Position des Arrays ist irrelevant. Und Sie können das Array nach sortieren name of the student.
Donovan
@ Gordon technisch ist es wahr. Der Programmierer gibt jedoch eine Zahl und keine Zeichenfolge an. Ich denke, das ist die Bedeutung von without using a key string.
Donovan
2
@ Albert Sie ordnen diese Nummer der entsprechenden Schlüsselzeichenfolge zu. Das heißt array[1] === $array['foo']aber nicht. Das Array könnte noch einen anderen Wert bei enthalten $array[1]. Beachten Sie, dass ich nicht sage, dass Ihre Lösung falsch ist. Es ist die Annahme des OP.
Gordon
27

Es gibt keine Korrelation zwischen numerischen und assoziativen Indexschlüsseln.

Wenn Sie sagen, dass Sie den Wert eines assoziativen Arrays mithilfe des Array-Index des Schlüssels / Werts festlegen möchten , müssen Sie den angegebenen Schlüssel verwenden. Die Einstellung entspricht $array[1]nicht der Einstellung $array['foo'].

Betrachten Sie dieses Array

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

Dies wird geben

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

Das foo ist das zweite Element im Array. Das ist der Offset , hat aber nichts mit dem Index 1 zu tun. Wie Sie sehen können, ist in diesem Array oben Index 1 zugeordnet baz. Es ist falsch anzunehmen, dass nur weil fooes der erste assoziative Schlüssel ist, er irgendetwas mit dem tatsächlichen numerischen Schlüssel 1 zu tun hat. Genau wie somekorreliert nicht mit 2.

Ebenso array_keysfunktioniert für ein gemischtes Array wie oben gezeigt die Lösung, die an anderer Stelle auf dieser Site vorgeschlagen wird, nicht, weil

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

wird geben

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

Wenn du es tust $array[$keys[1]], tust du es wirklich $array['foo']. Aber wenn man den zweiten assoziativen Wert in diesem Array (zuzugreifen will 'some'), können Sie nicht tun , $array[$keys[2]]weil das bewerten würde $array[1]und das ist baz.

Der Versatz eines Elements hängt überhaupt nicht mit seinem Schlüssel oder Wert zusammen

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

bedeutet wirklich

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

Dies bedeutet, dass das Element bei Offset 0 foo ist, obwohl sein Schlüssel 100 ist. Wenn Sie Elemente aus einem Array durch Offset extrahieren möchten, müssen Sie verwenden

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

Dies würde ein Array erzeugen, das nur das Element an der dritten Position hält.

Oder Sie könnten eine verwenden ArrayIterator. Das ArrayIteratorimplementiert eine SeekableSchnittstelle, mit der Sie nach einer bestimmten Position / einem bestimmten Versatz im Array suchen und dann Folgendes abrufen können:

$iterator = new ArrayIterator($array);
$iterator->seek(3);
echo $iterator->current(); // value
Gordon
quelle
Minor nit: „Wenn Sie den zweiten assoziativen Wert in diesem Array (‚some‘) zugreifen wollen, Sie $ array nicht tun kann [$ Tasten [2]] , weil das zu $ array bewerten würde [1] und dass Baz“ Technisch gesehen , Das liegt daran, dass alle Schlüssel, einschließlich der numerischen, assoziative Schlüssel sind - die 4 von zurückgegebenen Werte array_keys. Es gibt keine Entität wie einen "nicht assoziativen Schlüssel". Wenn Sie darauf hinweisen wollten, dass Sie den zweiten Zeichenfolgenschlüssel nicht zurückgeben können (indem Sie davon ausgehen, dass das Schlüsselarray nur Zeichenfolgen enthält), ist das, was Sie sagen, richtig. $stringKeys = array_filter(array_keys($array), "is_string");gibt String-Schlüssel.
ToolmakerSteve
17

Während array_keys()Zugriff auf die n - te Schlüssel ermöglicht, array_valueswerden Sie den n - te Wert.

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

gibt 'Zwei' aus.

Gibt es einen Vorteil gegenüber dem anderen? Nun, die einzige Kleinigkeit, die ich sehen kann, ist die Anzahl der Array-Zugriffe.

Mit müssen array_keys()Sie 3.

  1. Holen Sie sich die Schlüssel aus dem Datenarray.
  2. Holen Sie sich den n-ten Schlüssel aus der Liste der Schlüssel.
  3. Rufen Sie den Wert mit dem n-ten Schlüssel aus dem Datenarray ab.

Mit array_values()brauchen Sie nur 2.

  1. Holen Sie sich die Werte aus dem Datenarray.
  2. Holen Sie sich den n-ten Wert aus der Werteliste.

Andererseits sind die Schlüssel normalerweise kleiner und die Daten können sehr verschachtelt sein. Unter dem Strich ist die Verwendung von array_keys()wahrscheinlich sicherer.

Richard A Quadling
quelle
3

Wenn das Array groß ist, sind beide array_keysund array_valuesverschwenderisch, da sie ein neues Array mit der gleichen Größe wie das Original zuweisen, nur um den n-ten Schlüssel (oder Wert) zu erhalten.

array_sliceakzeptiert einen ganzzahligen Offset und arbeitet mit assoziativen Arrays. Sie können es verwenden, um den n-ten Schlüssel in konstanter Zeit abzurufen (und festzulegen) .

// 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;
Jesse
quelle
2
Schöne Lösung hier!
Daan
1

Versuche dies. Es funktioniert für Sie.

$result= array_values($my_arr); // Array with indexes you need
Murali krishna
quelle
1
Bitte seien Sie vorsichtig, wenn Sie in einem alten Thread posten, der bereits mehrere Antworten und eine akzeptierte Antwort enthält. Sie müssen erklären, warum Ihre neue Antwort besser ist als die vorhandene.
APC
0

Eine andere Möglichkeit besteht darin, es in ein normales Array zu konvertieren:

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

Wobei "~~~" ein Trennzeichen ist, das in Ihren Daten nicht vorkommt.

Jetzt können Sie mit numerischen Indizes, die den Offsets entsprechen, auf das Array zugreifen.

Wenn Sie Ihr assoziatives Array weiterhin beibehalten müssen, weisen Sie es einfach einer anderen Variablen zu.

Phreditor
quelle
Da Sie immer und immer berücksichtigen sollten, dass dieses genaue Trennzeichen in Ihren Daten vorkommen kann, funktioniert diese Idee nur in 99,9999999%. Es gibt mehrere Lösungen, die zu 100% funktionieren. Außerdem setzt dies den Prozessor auf eine Menge Arbeit und verschwendeten Speicher für nur einen einfachen Array-Zugriff.
user426486