PHP : 배열 키 대소 문자를 구분하지 않음 * 조회?
$myArray = array ('SOmeKeyNAme' => 7);
나는 $myArray['somekeyname']
돌아가고 싶다 7
.
배열을 조작하지 않고이를 수행 할 수있는 방법이 있습니까?
배열을 만들지 않으므로 키를 제어 할 수 없습니다.
옵션 1-어레이 생성 방식 변경
선형 검색을하지 않거나 원래 배열을 변경하지 않고는이를 수행 할 수 없습니다. 가장 효율적인 방법은 값을 조회 할 때 AND를 삽입 할 때 키에 strtolower 를 사용하는 것 입니다.
$myArray[strtolower('SOmeKeyNAme')]=7;
if (isset($myArray[strtolower('SomekeyName')]))
{
}
키의 원래 대소 문자를 유지하는 것이 중요한 경우 해당 키에 대한 추가 값으로 저장할 수 있습니다.
$myArray[strtolower('SOmeKeyNAme')]=array('SOmeKeyNAme', 7);
옵션 2-보조 매핑 생성
이것이 가능하지 않다는 질문을 업데이트했을 때 소문자와 대소 문자 구분 버전 간의 매핑을 제공하는 배열을 만드는 것은 어떻습니까?
$keys=array_keys($myArray);
$map=array();
foreach($keys as $key)
{
$map[strtolower($key)]=$key;
}
이제 이것을 사용하여 소문자에서 대소 문자 구분 키를 얻을 수 있습니다.
$test='somekeyname';
if (isset($map[$test]))
{
$value=$myArray[$map[$test]];
}
이렇게하면 소문자 키를 사용하여 배열의 전체 복사본을 만들 필요가 없습니다. 이는 실제로이 문제를 해결하는 유일한 다른 방법입니다.
옵션 3-어레이 사본 생성
배열의 전체 복사본을 만드는 것이 문제가되지 않는 경우 array_change_key_case 를 사용하여 소문자 키로 복사본을 만들 수 있습니다 .
$myCopy=array_change_key_case($myArray, CASE_LOWER);
나는 이것이 오래된 질문이라는 것을 알고 있지만이 문제를 처리하는 가장 우아한 방법은 다음을 사용하는 것입니다.
array_change_key_case($myArray); //second parameter is CASE_LOWER by default
귀하의 예에서 :
$myArray = array ('SOmeKeyNAme' => 7);
$myArray = array_change_key_case($myArray);
이후 $ myArray에는 모든 소문자 키가 포함됩니다.
echo $myArray['somekeyname'] will contain 7
또는 다음을 사용할 수 있습니다.
array_change_key_case($myArray, CASE_UPPER);
문서는 여기에서 볼 수 있습니다 : http://us3.php.net/manual/en/function.array-change-key-case.php
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']
저는 키 매핑을 만드는 Paul Dixon의 아이디어와 PHP 배열에 접근하는 익숙한 방법을 유지하기 위해 ArrayAccess 인터페이스를 사용하는 Kendall Hopkins의 아이디어를 결합했습니다 .
결과는 초기 배열 복사를 피하고 대소 문자를 구분하지 않는 투명한 액세스를 허용하는 동시에 키의 대소 문자를 내부적으로 보존하는 클래스입니다. 제한 : 대소 문자를 구분하지 않는 동일한 키 (예 : 'Foo'및 'foo')가 초기 배열에 포함되어 있거나 동적으로 추가되면 후자의 항목이 이전 항목을 덮어 씁니다 (액세스 불가능하게 렌더링 됨).
물론 많은 경우 $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/en/function.array-key-exists.php#108226
또한 (첫 번째) 대소 문자를 구분하지 않는 키 일치를 반환하는 방법이 필요했습니다. 내가 생각 해낸 것은 다음과 같습니다.
/**
* 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' ]
}
}
In my case I wanted an efficient workaround where my program was already creating the array using a foreach loop from customer data having unknown case, and I wanted to preserve the customer's case for later display in the program.
My solution was to create a separate array $CaseMap to map a given lowercase key to the mixedcase key used in the array (irrelevant code is omitted here):
$CaseMap=[];
foreach ($UserArray as $Key=>$Value)
$CaseMap[strtolower($Key)]=$Key;
Then lookup is like this:
$Value=$UserArray[$CaseMap("key")];
and the memory overhead is just the $CaseMap array, which maps presumably short keys to short keys.
I'm not sure if PHP has a more efficient way to generate $CaseMap in the case where I'n not already using foreach.
I just had same problem and I could not change original array. I use few array functions for it.
Parameters
$search = "AbCd";
$array = array("AbcD"=>"11","Bb"=>"22");
Solution
$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];
Make it shorter
if(($idx=array_search(strtolower($search),array_map("strtolower",array_keys($array))))!==FALSE)
echo array_values($array)[$idx];
I know this is old, but in case anyone else needs a quick easy way to do this without actually 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
참고URL : https://stackoverflow.com/questions/4240001/php-array-keys-case-insensitive-lookup
'development' 카테고리의 다른 글
개체가 VBA에서 컬렉션의 구성원인지 확인 (0) | 2020.12.03 |
---|---|
Scala에서 빈 배열에 대한 정식 방법? (0) | 2020.12.03 |
Parcelable 인터페이스를 사용할 때 null 값을 직렬화하는 방법 (0) | 2020.12.03 |
여러 String.Replaces의 대안 (0) | 2020.12.03 |
자리 표시 자 텍스트 변경 (0) | 2020.12.03 |