Php: Array key case * insensitive * search?

$myArray = array ('SOmeKeyNAme' => 7); 

I want $myArray['somekeyname'] to return 7 .
Is there a way to do this without manipulating the array?

I do not create an array, so it cannot control its keys

+59
arrays php
Nov 21 '10 at 19:56
source share
11 answers

Option 1 - change the way you create the array

You cannot do this without linearly searching or modifying the original array. The most efficient approach would be to use strtolower on the keys when you insert AND when searching for values.

  $myArray[strtolower('SOmeKeyNAme')]=7; if (isset($myArray[strtolower('SomekeyName')])) { } 

If it is important for you to keep the original case of the key, you can save it as an additional value for this key, for example.

 $myArray[strtolower('SOmeKeyNAme')]=array('SOmeKeyNAme', 7); 

Option 2 - create a secondary display

How did you update the question to suggest that it would be impossible for you, how about creating an array that provides comparisons between lowercase and lowercase versions?

 $keys=array_keys($myArray); $map=array(); foreach($keys as $key) { $map[strtolower($key)]=$key; } 

Now you can use this to get the case sensitive key from the bottom

 $test='somekeyname'; if (isset($map[$test])) { $value=$myArray[$map[$test]]; } 

This avoids the need to create a full copy of the array with a key with a lower value, which is actually the only way to do this.

Option 3 - Create a copy of the array

If a full copy of the array is not a concern, you can use array_change_key_case to create a copy with the lower case keys.

 $myCopy=array_change_key_case($myArray, CASE_LOWER); 
+72
Nov 21 '10 at 19:59
source share

I know this is an old question, but the most elegant way to deal with this problem is to use:

 array_change_key_case($myArray); //second parameter is CASE_LOWER by default 

In your example:

 $myArray = array ('SOmeKeyNAme' => 7); $myArray = array_change_key_case($myArray); 

Subsequently, $ myArray will contain all lowercase letters:

 echo $myArray['somekeyname'] will contain 7 

Alternatively you can use:

 array_change_key_case($myArray, CASE_UPPER); 

The documentation can be viewed here: http://us3.php.net/manual/en/function.array-change-key-case.php

+41
Apr 28 '13 at 6:10
source share

You can use the ArrayAccess interface to create a class that works with array syntax.

Example

 $lower_array_object = new CaseInsensitiveArray; $lower_array_object["thisISaKEY"] = "value"; print $lower_array_object["THISisAkey"]; //prints "value" 

or

 $lower_array_object = new CaseInsensitiveArray( array( "SoMeThInG" => "anything", ... ) ); print $lower_array_object["something"]; //prints "anything" 

Class

 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; } } 
+14
Nov 21 2018-10-21T00:
source share

A simple but maybe expensive way is to create a copy, then use array_change_key_case($array_copy, CASE_LOWER) , and then access array_copy['somekeyname']

+14
Nov 21 '10 at 20:10
source share

I combined Paul Dixon’s idea of ​​creating a key mapping with Kendall Hopkins’s idea of ​​using the ArrayAccess interface to preserve a familiar way to access a PHP array.

The result is a class that avoids copying the original array and provides transparent, case-insensitive access, while retaining keys internally. Restriction: if keys that are not case sensitive (for example, "Foo" and "foo") are contained in the initial array or are dynamically added, then the last records will overwrite the previous ones (which makes them inaccessible).

Admittedly, in many cases its (imo) is much more straightforward to simply enter the keys $lowercasedKeys = array_change_key_case($array, CASE_LOWER); as suggested by Mikpa.

Class CaseInsensitiveKeysArray

 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; } } } 
+2
Apr 09 2018-12-14T00:
source share

From PHP site

 function array_ikey_exists($key, $haystack){ return array_key_exists(strtolower($key), array_change_key_case($haystack)); } 

Link: http://us1.php.net/manual/en/function.array-key-exists.php#108226

+2
Nov 12 '13 at 22:34
source share

If you assign them to an array, you can enter lowercase letters, as well as in line-by-line viewing of values.

Without changing the array, but the entire data structure:

Actually, the cumbersome way is to create getter / setter magic methods, but would it really be worth the effort (note that other methods also need to be implemented)?

 <?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; } } 
+1
Nov 21 '10 at 19:59
source share

I also need a way to return a (first) case-sensitive match. Here is what I came up with:

 /** * 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; } 

So, to answer the original question:

 $myArray = array('SOmeKeyNAme' => 7); $test = 'somekeyname'; $key = get_array_ikey($test, $myArray); if ($key !== false) { echo $myArray[$key]; } 
+1
Aug 31 '15 at 5:54
source share

You can manually scroll the array and look for a match.

 foreach( $myArray as $key => $value ) { if( strtolower( $key ) == 'somekeyname' ) { // match found, $value == $myArray[ 'SOmeKeyNAme' ] } } 
0
Nov 21 '10 at 20:09
source share

In my case, I wanted an efficient workaround when my program already created an array using the foreach loop from client data having an unknown case, and I wanted to save the client case for later display in the program.

My solution was to create a separate $ CaseMap array to map the given key in lower case to the mixed key used in the array (the irrelevant code is omitted here):

 $CaseMap=[]; foreach ($UserArray as $Key=>$Value) $CaseMap[strtolower($Key)]=$Key; 

Then the search looks like this:

 $Value=$UserArray[$CaseMap("key")]; 

and the memory overhead is just an $ CaseMap array that maps presumably short keys to short keys.

I'm not sure if PHP has a more efficient way to generate $ CaseMap when I haven't used foreach yet.

0
Jun 30 '19 at 14:02
source share

I know this is old, but in case someone needs a quick easy way to do this without changing the original array:

 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 
-one
Aug 21 '14 at 18:14
source share



All Articles