Ich denke, es ist unmöglich, dies zu tun, ohne das Array zu ändern oder zu kopieren. Sie können das Array kopieren und den Schlüsselfall mit der PHP-Funktion array_change_key_case ändern.
ynh
Dies ist die am meisten geschätzte Antwort, aber sie steht in einem Kommentar ... Ich fragte, ob das oben
Genannte
Alles ist möglich. PHP ist Open Source, es geht also nur darum, einige Interna zu ändern und neu zu kompilieren;)
dev-null-
Ich frage mich, ob es möglich ist, mehrere Schlüssel für Ihre eigentliche Aufgabe zuzuordnen. Wenn Sie wissen, dass alle Schlüssel eindeutig sind, beispielsweise nachdem sie alle in Kleinbuchstaben konvertiert wurden, müssen Sie nicht alle Schlüssel aktualisieren, sondern nur das Array iterieren und einen Vergleich der Schlüssel ohne Berücksichtigung der Groß- und Kleinschreibung durchführen . Wichtig ist, dass Sie ein breakoder verwenden return, sobald die Übereinstimmung gefunden wurde, damit keine unnötigen Iterationen durchgeführt werden. Wenn Sie die Möglichkeit des Abgleichs mehrerer Schlüssel berücksichtigen müssen, müssen Sie alle iterieren UND alle nach unten / oben zwingen, um Ihre Daten tatsächlich zu beschädigen.
Mickmackusa
Antworten:
89
Option 1 - Ändern Sie die Art und Weise, wie Sie das Array erstellen
Sie können dies nicht tun, ohne eine lineare Suche durchzuführen oder das ursprüngliche Array zu ändern. Der effizienteste Ansatz besteht darin, strtolower für Tasten zu verwenden, wenn Sie AND einfügen und Werte nachschlagen .
$myArray[strtolower('SOmeKeyNAme')]=7;
if (isset($myArray[strtolower('SomekeyName')]))
{
}
Wenn es Ihnen wichtig ist, den ursprünglichen Fall des Schlüssels beizubehalten, können Sie ihn als zusätzlichen Wert für diesen Schlüssel speichern, z
Wenn Sie die Frage aktualisiert haben, um darauf hinzuweisen, dass dies für Sie nicht möglich ist, können Sie ein Array erstellen, das eine Zuordnung zwischen Versionen mit Kleinbuchstaben und Versionen mit Groß- und Kleinschreibung bietet.
Jetzt können Sie dies verwenden, um die Groß- und Kleinschreibung von einem Kleinbuchstaben zu erhalten
$test='somekeyname';
if (isset($map[$test]))
{
$value=$myArray[$map[$test]];
}
Dadurch wird vermieden, dass eine vollständige Kopie des Arrays mit einem Schlüssel in Kleinbuchstaben erstellt werden muss. Dies ist wirklich der einzige andere Weg, um dies zu erreichen.
Option 3 - Erstellen Sie eine Kopie des Arrays
Wenn das Erstellen einer vollständigen Kopie des Arrays kein Problem darstellt , können Sie mit array_change_key_case eine Kopie mit Schlüsseln mit niedrigerem Gehäuse erstellen.
@xpy: Wollte das gleiche vorschlagen, sollte auch effizienter sein.
Alix Axel
@xpy Das ist die wahre Antwort! Ich verwende Oracle- und MySQL-Datenbanken und sie geben Groß- / Kleinbuchstaben zurück, sodass "Ändern der Art und Weise, wie Sie die Schlüssel erstellen" nicht möglich ist. Dieser Kommentar hat die Inkompatibilität gut gelöst!
Pid
Obwohl Header per se nicht UTF-8 sind, würde ich $ map [mb_strtolower ($ key)] = $ key verwenden; PHPs Multibyte-Funktionen zu nutzen.
Noderman
48
Ich weiß, dass dies eine ältere Frage ist, aber der eleganteste Weg, um dieses Problem zu lösen, ist die Verwendung von:
array_change_key_case($myArray); //second parameter is CASE_LOWER by default
Eine einfache, aber möglicherweise teure Möglichkeit besteht darin, eine Kopie zu erstellen, diese dann zu verwenden array_change_key_case($array_copy, CASE_LOWER)und anschließend darauf zuzugreifenarray_copy['somekeyname']
array_change_key_caseändert das Array nicht. Es wird eine Kopie des Arrays zurückgegeben.
Martin Prikryl
2
Ich kombinierte Paul Dixons Idee, ein Mapping für die Schlüssel zu erstellen, und Kendall Hopkins 'Idee, die ArrayAccess- Schnittstelle zu verwenden, um die vertraute Art des Zugriffs auf ein PHP-Array beizubehalten .
Das Ergebnis ist eine Klasse, die das Kopieren des ursprünglichen Arrays vermeidet und einen transparenten Zugriff ohne Berücksichtigung der Groß- und Kleinschreibung ermöglicht, während die Groß- und Kleinschreibung der Schlüssel intern beibehalten wird. Einschränkung: Wenn Groß- und Kleinschreibung ohne Berücksichtigung der Groß- und Kleinschreibung (z. B. 'Foo' und 'foo') im ursprünglichen Array enthalten sind oder dynamisch hinzugefügt werden, überschreiben letztere Einträge die vorherigen (wodurch diese nicht mehr zugänglich sind).
Zugegeben, in vielen Fällen ist es (imo) viel einfacher, die Tasten nur in Kleinbuchstaben zu $lowercasedKeys = array_change_key_case($array, CASE_LOWER);schreiben, wie von Mikpa vorgeschlagen.
Ich brauchte auch eine Möglichkeit, um (die erste) Schlüsselübereinstimmung ohne Berücksichtigung der Groß- und Kleinschreibung zurückzugeben. Folgendes habe ich mir ausgedacht:
Sie können Ihre Schlüssel in Kleinbuchstaben schreiben, wenn Sie sie dem Array zuweisen, und sie auch in Kleinbuchstaben, wenn Sie den Wert nachschlagen.
Ohne das Array zu ändern, aber die gesamte Datenstruktur:
Ein wirklich umständlicher Weg besteht darin, Magic Getter / Setter-Methoden zu erstellen, aber wäre es wirklich die Mühe wert (beachten Sie, dass auch die anderen Methoden implementiert werden müssen)?
In meinem Fall wollte ich eine effiziente Problemumgehung, bei der mein Programm das Array bereits mithilfe einer foreach-Schleife aus Kundendaten mit unbekanntem Fall erstellt hat, und ich wollte den Fall des Kunden für die spätere Anzeige im Programm beibehalten.
Meine Lösung bestand darin, ein separates Array $ CaseMap zu erstellen, um einen bestimmten Kleinbuchstabenschlüssel dem im Array verwendeten Mixedcase-Schlüssel zuzuordnen (irrelevanter Code wird hier weggelassen):
Es scheint, dass Sie die beiden wichtigsten Antworten, die array_change_key_case()viele Jahre zuvor empfohlen wurden, nicht gelesen haben.
Mickmackusa
@ Mickmackusa Du hast recht. Ich habe versucht, Code zu erstellen, der keine Kopie von Werten erstellt. Aber ich habe nicht gefangen "array_values" macht auch kopieren. Das ist nichts besseres.
CN Lee
-1
Ich weiß, dass dies alt ist, aber falls jemand anderes eine schnelle und einfache Möglichkeit benötigt, dies zu tun, ohne das ursprüngliche Array tatsächlich zu ändern:
break
oder verwendenreturn
, sobald die Übereinstimmung gefunden wurde, damit keine unnötigen Iterationen durchgeführt werden. Wenn Sie die Möglichkeit des Abgleichs mehrerer Schlüssel berücksichtigen müssen, müssen Sie alle iterieren UND alle nach unten / oben zwingen, um Ihre Daten tatsächlich zu beschädigen.Antworten:
Option 1 - Ändern Sie die Art und Weise, wie Sie das Array erstellen
Sie können dies nicht tun, ohne eine lineare Suche durchzuführen oder das ursprüngliche Array zu ändern. Der effizienteste Ansatz besteht darin, strtolower für Tasten zu verwenden, wenn Sie AND einfügen und Werte nachschlagen .
$myArray[strtolower('SOmeKeyNAme')]=7; if (isset($myArray[strtolower('SomekeyName')])) { }
Wenn es Ihnen wichtig ist, den ursprünglichen Fall des Schlüssels beizubehalten, können Sie ihn als zusätzlichen Wert für diesen Schlüssel speichern, z
$myArray[strtolower('SOmeKeyNAme')]=array('SOmeKeyNAme', 7);
Option 2 - Erstellen Sie eine sekundäre Zuordnung
Wenn Sie die Frage aktualisiert haben, um darauf hinzuweisen, dass dies für Sie nicht möglich ist, können Sie ein Array erstellen, das eine Zuordnung zwischen Versionen mit Kleinbuchstaben und Versionen mit Groß- und Kleinschreibung bietet.
$keys=array_keys($myArray); $map=array(); foreach($keys as $key) { $map[strtolower($key)]=$key; }
Jetzt können Sie dies verwenden, um die Groß- und Kleinschreibung von einem Kleinbuchstaben zu erhalten
$test='somekeyname'; if (isset($map[$test])) { $value=$myArray[$map[$test]]; }
Dadurch wird vermieden, dass eine vollständige Kopie des Arrays mit einem Schlüssel in Kleinbuchstaben erstellt werden muss. Dies ist wirklich der einzige andere Weg, um dies zu erreichen.
Option 3 - Erstellen Sie eine Kopie des Arrays
Wenn das Erstellen einer vollständigen Kopie des Arrays kein Problem darstellt , können Sie mit array_change_key_case eine Kopie mit Schlüsseln mit niedrigerem Gehäuse erstellen.
$myCopy=array_change_key_case($myArray, CASE_LOWER);
quelle
Ich weiß, dass dies eine ältere Frage ist, aber der eleganteste Weg, um dieses Problem zu lösen, ist die Verwendung von:
array_change_key_case($myArray); //second parameter is CASE_LOWER by default
In Ihrem Beispiel:
$myArray = array ('SOmeKeyNAme' => 7); $myArray = array_change_key_case($myArray);
Danach enthält $ myArray alle Kleinbuchstaben:
echo $myArray['somekeyname'] will contain 7
Alternativ können Sie verwenden:
array_change_key_case($myArray, CASE_UPPER);
Die Dokumentation finden Sie hier: http://us3.php.net/manual/en/function.array-change-key-case.php
quelle
Sie können die
ArrayAccess
Schnittstelle verwenden, um eine Klasse zu erstellen, die mit der Array-Syntax arbeitet.Beispiel
$lower_array_object = new CaseInsensitiveArray; $lower_array_object["thisISaKEY"] = "value"; print $lower_array_object["THISisAkey"]; //prints "value"
oder
$lower_array_object = new CaseInsensitiveArray( array( "SoMeThInG" => "anything", ... ) ); print $lower_array_object["something"]; //prints "anything"
Klasse
class CaseInsensitiveArray implements ArrayAccess { private $_container = array(); public function __construct( Array $initial_array = array() ) { $this->_container = array_map( "strtolower", $initial_array ); } public function offsetSet($offset, $value) { if( is_string( $offset ) ) $offset = strtolower($offset); if (is_null($offset)) { $this->container[] = $value; } else { $this->container[$offset] = $value; } } public function offsetExists($offset) { if( is_string( $offset ) ) $offset = strtolower($offset); return isset($this->_container[$offset]); } public function offsetUnset($offset) { if( is_string( $offset ) ) $offset = strtolower($offset); unset($this->container[$offset]); } public function offsetGet($offset) { if( is_string( $offset ) ) $offset = strtolower($offset); return isset($this->container[$offset]) ? $this->container[$offset] : null; } }
quelle
Eine einfache, aber möglicherweise teure Möglichkeit besteht darin, eine Kopie zu erstellen, diese dann zu verwenden
array_change_key_case($array_copy, CASE_LOWER)
und anschließend darauf zuzugreifenarray_copy['somekeyname']
quelle
array_change_key_case
ändert das Array nicht. Es wird eine Kopie des Arrays zurückgegeben.Ich kombinierte Paul Dixons Idee, ein Mapping für die Schlüssel zu erstellen, und Kendall Hopkins 'Idee, die ArrayAccess- Schnittstelle zu verwenden, um die vertraute Art des Zugriffs auf ein PHP-Array beizubehalten .
Das Ergebnis ist eine Klasse, die das Kopieren des ursprünglichen Arrays vermeidet und einen transparenten Zugriff ohne Berücksichtigung der Groß- und Kleinschreibung ermöglicht, während die Groß- und Kleinschreibung der Schlüssel intern beibehalten wird. Einschränkung: Wenn Groß- und Kleinschreibung ohne Berücksichtigung der Groß- und Kleinschreibung (z. B. 'Foo' und 'foo') im ursprünglichen Array enthalten sind oder dynamisch hinzugefügt werden, überschreiben letztere Einträge die vorherigen (wodurch diese nicht mehr zugänglich sind).
Zugegeben, in vielen Fällen ist es (imo) viel einfacher, die Tasten nur in Kleinbuchstaben zu
$lowercasedKeys = array_change_key_case($array, CASE_LOWER);
schreiben, wie von Mikpa vorgeschlagen.Die CaseInsensitiveKeysArray-Klasse
class CaseInsensitiveKeysArray implements ArrayAccess { private $container = array(); private $keysMap = array(); public function __construct(Array $initial_array = array()) { $this->container = $initial_array; $keys = array_keys($this->container); foreach ($keys as $key) { $this->addMappedKey($key); } } public function offsetSet($offset, $value) { if (is_null($offset)) { $this->container[] = $value; } else { $this->container[$offset] = $value; $this->addMappedKey($offset); } } public function offsetExists($offset) { if (is_string($offset)) { return isset($this->keysMap[strtolower($offset)]); } else { return isset($this->container[$offset]); } } public function offsetUnset($offset) { if ($this->offsetExists($offset)) { unset($this->container[$this->getMappedKey($offset)]); if (is_string($offset)) { unset($this->keysMap[strtolower($offset)]); } } } public function offsetGet($offset) { return $this->offsetExists($offset) ? $this->container[$this->getMappedKey($offset)] : null; } public function getInternalArray() { return $this->container; } private function addMappedKey($key) { if (is_string($key)) { $this->keysMap[strtolower($key)] = $key; } } private function getMappedKey($key) { if (is_string($key)) { return $this->keysMap[strtolower($key)]; } else { return $key; } } }
quelle
Von der PHP-Site
function array_ikey_exists($key, $haystack){ return array_key_exists(strtolower($key), array_change_key_case($haystack)); }
Referenz: http://us1.php.net/manual/en/function.array-key-exists.php#108226
quelle
Ich brauchte auch eine Möglichkeit, um (die erste) Schlüsselübereinstimmung ohne Berücksichtigung der Groß- und Kleinschreibung zurückzugeben. Folgendes habe ich mir ausgedacht:
/** * Case-insensitive search for present array key * @param string $needle * @param array $haystack * @return string|bool The present key, or false */ function get_array_ikey($needle, $haystack) { foreach ($haystack as $key => $meh) { if (strtolower($needle) == strtolower($key)) { return (string) $key; } } return false; }
Um die ursprüngliche Frage zu beantworten:
$myArray = array('SOmeKeyNAme' => 7); $test = 'somekeyname'; $key = get_array_ikey($test, $myArray); if ($key !== false) { echo $myArray[$key]; }
quelle
Sie können Ihre Schlüssel in Kleinbuchstaben schreiben, wenn Sie sie dem Array zuweisen, und sie auch in Kleinbuchstaben, wenn Sie den Wert nachschlagen.
Ohne das Array zu ändern, aber die gesamte Datenstruktur:
Ein wirklich umständlicher Weg besteht darin, Magic Getter / Setter-Methoden zu erstellen, aber wäre es wirklich die Mühe wert (beachten Sie, dass auch die anderen Methoden implementiert werden müssen)?
<?php class CaseInsensitiveArray { protected $m_values; public function __construct() { $this->m_values = array(); } public function __get($key) { return array_key_exists($key, $this->m_values) ? $this->m_values[$key] : null; } public function __set($key, $value) { $this->m_attributes[$key] = $value; } }
quelle
Sie können das Array manuell durchlaufen und nach einer Übereinstimmung suchen.
foreach( $myArray as $key => $value ) { if( strtolower( $key ) == 'somekeyname' ) { // match found, $value == $myArray[ 'SOmeKeyNAme' ] } }
quelle
In meinem Fall wollte ich eine effiziente Problemumgehung, bei der mein Programm das Array bereits mithilfe einer foreach-Schleife aus Kundendaten mit unbekanntem Fall erstellt hat, und ich wollte den Fall des Kunden für die spätere Anzeige im Programm beibehalten.
Meine Lösung bestand darin, ein separates Array $ CaseMap zu erstellen, um einen bestimmten Kleinbuchstabenschlüssel dem im Array verwendeten Mixedcase-Schlüssel zuzuordnen (irrelevanter Code wird hier weggelassen):
$CaseMap=[]; foreach ($UserArray as $Key=>$Value) $CaseMap[strtolower($Key)]=$Key;
Dann ist die Suche wie folgt:
$Value=$UserArray[$CaseMap("key")];
und der Speicheraufwand ist nur das $ CaseMap-Array, das vermutlich kurze Tasten kurzen Tasten zuordnet.
Ich bin mir nicht sicher, ob PHP eine effizientere Möglichkeit zum Generieren von $ CaseMap bietet, wenn ich foreach noch nicht verwende.
quelle
Ich hatte gerade das gleiche Problem und konnte das ursprüngliche Array nicht ändern. Ich benutze einige Array-Funktionen dafür.
Parameter
$search = "AbCd"; $array = array("AbcD"=>"11","Bb"=>"22");
Lösung
$lower_search = strtolower($search); $array_of_keys = array_map("strtolower",array_keys($array)); $idx = array_search($lower_search,$array_of_keys); if($idx !== FALSE) echo array_values($array)[$idx];
Mach es kürzer
if(($idx=array_search(strtolower($search),array_map("strtolower",array_keys($array))))!==FALSE) echo array_values($array)[$idx];
quelle
array_change_key_case()
viele Jahre zuvor empfohlen wurden, nicht gelesen haben.Ich weiß, dass dies alt ist, aber falls jemand anderes eine schnelle und einfache Möglichkeit benötigt, dies zu tun, ohne das ursprüngliche Array tatsächlich zu ändern:
function array_key_i($needle, $haystack){ $key=array_search(strtolower($search), array_combine(array_keys($array),array_map('strtolower', array_keys($array)))); return ($key!==false); } $array=array('TeSt1'=>'maybe'); $search='test1'; array_key_i($search, $array); // returns true
quelle