$myArray = array ('SOmeKeyNAme' => 7);
Ich möchte $myArray['somekeyname']zurückkehren 7.
Gibt es eine Möglichkeit, dies zu tun, ohne das Array zu manipulieren?
Ich erstelle das Array nicht und kann daher seine Schlüssel nicht steuern
$myArray = array ('SOmeKeyNAme' => 7);
Ich möchte $myArray['somekeyname']zurückkehren 7.
Gibt es eine Möglichkeit, dies zu tun, ohne das Array zu manipulieren?
Ich erstelle das Array nicht und kann daher seine Schlüssel nicht steuern
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.
Antworten:
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);
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.
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);
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
Sie können die ArrayAccessSchnittstelle 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;
}
}
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.
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;
}
}
}
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
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];
}
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;
}
}
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.
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];
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