$myArray = array ('SOmeKeyNAme' => 7);
我希望$myArray['somekeyname']
返回7
。 有没有一种方法可以在不操作数组的情况下实现这一点?我没有创建数组,因此无法控制其键。
如果不进行线性搜索或更改原始数组,无法完成此操作。最有效的方法是在插入和查找值时对键使用strtolower。
$myArray[strtolower('SOmeKeyNAme')]=7;
if (isset($myArray[strtolower('SomekeyName')]))
{
}
如果保留键的原始大小写很重要,您可以将其作为该键的附加值存储,例如:
$myArray[strtolower('SOmeKeyNAme')]=array('SOmeKeyNAme', 7);
既然您更新了问题,表示对您来说这不是可能的选择,那么您可以创建一个数组,提供小写和区分大小写版本之间的映射关系。
$keys=array_keys($myArray);
$map=array();
foreach($keys as $key)
{
$map[strtolower($key)]=$key;
}
现在你可以使用这个方法来从小写的键获取区分大小写的键
$test='somekeyname';
if (isset($map[$test]))
{
$value=$myArray[$map[$test]];
}
这避免了需要创建一个带小写键的完整副本的需要,这实际上是另一种处理方式。
如果不担心创建数组的完整副本,则可以使用array_change_key_case来创建具有小写键的副本。
$myCopy=array_change_key_case($myArray, CASE_LOWER);
array_key_exists(strtolower($key), array_change_key_case($myArray));
- SpYk3HHarray_change_key_case($myArray); //second parameter is CASE_LOWER by default
$myArray = array ('SOmeKeyNAme' => 7);
$myArray = array_change_key_case($myArray);
echo $myArray['somekeyname'] will contain 7
array_change_key_case($myArray, CASE_UPPER);
ArrayAccess
接口来创建一个支持数组语法的类。
示例:$lower_array_object = new CaseInsensitiveArray;
$lower_array_object["thisISaKEY"] = "value";
print $lower_array_object["THISisAkey"]; //prints "value"
或者$lower_array_object = new CaseInsensitiveArray(
array( "SoMeThInG" => "anything", ... )
);
print $lower_array_object["something"]; //prints "anything"
类
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;
}
}
一种简单但可能很昂贵的方法是先复制数组,然后使用 array_change_key_case($array_copy, CASE_LOWER)
,接着访问 array_copy['somekeyname']
array_change_key_case
不会修改数组。它返回数组的一个副本。 - Martin Prikryl$lowercasedKeys = array_change_key_case($array, CASE_LOWER);
将键转换为小写即可更加直观,正如Mikpa所建议的那样。
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;
}
}
}
来自 PHP 网站
function array_ikey_exists($key, $haystack){
return array_key_exists(strtolower($key), array_change_key_case($haystack));
}
参考资料:http://us1.php.net/manual/zh/function.array-key-exists.php#108226
该函数用于检查数组中是否存在指定的键名,如果存在则返回 true,否则返回 false。使用该函数可以避免在访问不存在的键名时出现错误。我还需要一种返回(第一个)不区分大小写的键匹配项的方法。以下是我想出来的方法:
/**
* 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;
}
$myArray = array('SOmeKeyNAme' => 7);
$test = 'somekeyname';
$key = get_array_ikey($test, $myArray);
if ($key !== false) {
echo $myArray[$key];
}
在将键分配给数组时,您可以将它们转换为小写,并在查找值时也将它们转换为小写。
而不修改数组,但修改整个数据结构:
一种非常繁琐的方法涉及创建魔术 getter/setter 方法,但这真的值得付出努力吗(请注意,其他方法也必须实现)?
<?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;
}
}
foreach( $myArray as $key => $value ) {
if( strtolower( $key ) == 'somekeyname' ) {
// match found, $value == $myArray[ 'SOmeKeyNAme' ]
}
}
我曾经遇到过同样的问题,但是我无法更改原始数组。我使用了一些数组函数来解决它。
参数
$search = "AbCd";
$array = array("AbcD"=>"11","Bb"=>"22");
解决方案
$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];
让它更短
if(($idx=array_search(strtolower($search),array_map("strtolower",array_keys($array))))!==FALSE)
echo array_values($array)[$idx];
array_change_key_case()
。 - mickmackusa
break
或return
来找到匹配项,以便不进行不必要的迭代。如果你需要适应匹配多个键的可能性,那么你将需要迭代所有的键,并强制所有键转换为小写/大写实际上会破坏你的数据。 - mickmackusa