programing

php: 어레이 키 케이스 *insensitive* lookup?

shortcode 2023. 1. 8. 15:11
반응형

php: 어레이 키 케이스 *insensitive* lookup?

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

는 는고되 i i i want want i를 원한다.$myArray['somekeyname']7.
어레이를 조작하지 않고 이 작업을 수행할 수 있는 방법이 있습니까?

어레이를 작성하지 않기 때문에 키를 제어할 수 없습니다.

옵션 1 - 어레이 작성 방법 변경

선형 검색 또는 원래 어레이를 변경하지 않으면 이 작업을 수행할 수 없습니다.가장 효율적인 방법은 AND를 삽입할 때 스트롤러를 키에 사용하는 것입니다.

 $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 를 참조해 주세요.

인터페이스를 사용하여 배열 구문을 사용하는 클래스를 만들 수 있습니다.

$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];
}

키를 어레이에 할당할 때는 소문자로, 값을 검색할 때는 소문자로 입력할 수도 있습니다.

어레이를 수정하지 않고 전체 데이터 구조를 수정하면 다음과 같습니다.

매우 번거로운 방법은 매직게터/세터 메서드를 만드는 것입니다만, 정말로 노력할 가치가 있을까요(다른 메서드도 실장해야 합니다).

<?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' ]
    }
}

제 경우, 프로그램이 이미 알 수 없는 케이스의 고객 데이터로부터 포어치 루프를 사용하여 어레이를 만들고 있는 효율적인 회피책을 원했습니다.또, 고객의 케이스는 나중에 프로그램에 표시할 수 있도록 보존하고 싶었습니다.

이 솔루션은 별도의 어레이 $CaseMap을 생성하여 지정된 소문자 키를 어레이에서 사용되는 혼합 케이스 키에 매핑하는 것이었습니다(여기에서는 관련 없는 코드가 생략됩니다).

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

그 후 룩업은 다음과 같습니다.

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

메모리의 오버헤드는 $CaseMap 어레이에 불과하며 단축키를 단축키에 매핑할 가능성이 있습니다.

아직 Foreach를 사용하지 않은 경우 PHP가 $CaseMap을 생성하는 더 효율적인 방법을 가지고 있는지 모르겠습니다.

같은 문제가 발생하여 원래 어레이를 변경할 수 없었습니다.어레이 기능은 거의 사용하지 않습니다.

파라미터

$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];

오래된 것은 알지만, 실제로 원래 어레이를 변경하지 않고 바로 이 작업을 수행할 수 있는 간단한 방법이 필요한 경우:

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

반응형