2015-01-18 4 views
0

API에서 큰 다차원 배열을받습니다. 배열을 클래스 속성으로 저장 한 다음 마법 getter를 사용하여 배열을 가장하고 최종 사용자가 키를 속성 ($class->key ==> $class->data['key'])으로 사용하게합니다.PHP 키로 다차원 배열에서 값 찾기

이제 다루는 배열은 매우 다차원 적이며 다른 "레벨"또는 레이어의 키가 필요합니다. 배열에 여러 개의 레이어가있는 두 개의 분기가 있다고 상상해보십시오.

내가 찾고있는 키는 일반적으로 최상위 수준입니다.

나는이 설명하기 위해 노력할 것입니다 : 내가 baseKey, key, subKeysubSubKey을 포함하여 내가 어떤 키를 줄 수있는 기능을 찾고

Array 
    baseKey 
     key1 
      value1 
     key2 
      value2 
     key3 
      subKey1 
       value3 
      subKey2 
       value4 
    key4 
     value5 
    key5 
     subKey3 
      value6 
    key6 
     subKey4 
      subSubKey1 
       value7 

을 그 첫 번째에 대한 각각의 값을 반환합니다 일치하는 키. 그래서 예를 들어

:

awesomeFindByKey('key2') 
    ==> value2 

awesomeFindByKey('subKey4') 
    ==> array('subSubKey1' => 'value7') 

awesomeFindByKey('key6') 
    ==> array('subKey4' => array('subSubKey1' => 'value7')) 

는 기능이 거기 아니면 내가 하나를 자신을 작성해야합니까? 아무도이 일을하는 함수를 가지고 있을까요?

이해할 수 있기를 바랍니다. 감사.

+2

재귀 링 벨? –

+0

array_map을 사용할 필요가없는 함수가 있는지 궁금합니다. – aFreshMelon

+0

array_map을 사용하여 withouth 함수를 작성할 수 있습니다. –

답변

-1

배열이 클래스 내에 저장되어있는 경우 PHP에서 제공하는 ArrayAccess 인터페이스를 구현할 수 있습니다. 이렇게하면 다른 언어 구문으로 (내부) 배열을 사용할 수있을뿐 아니라 클래스 자체를 배열로 사용할 수 있습니다.

예 :

$value = $class['base_key']['key']['sub_key']; 

이것은 또한 당신이 원하는대로 당신은 많은 수준을 가질 수있는 장점이있다. 제 생각에 이것은 3 단계 깊이 배열 만 처리 할 수있는 기능보다 훨씬 편리하다고 생각합니다.

UPDATE

제안 된 함수에 대한 가능한 구현은 다음과 같이 수 : (코멘트에 Karoly Hovarth에 의해 제안 된)

public function resolve_key($key, $array) { 

    /* 
    * Check if the key exists in the first array level. 
    */ 
    if(array_key_exists($key, $array)) { 
     return $array[$key]; 
    } 

    /* 
    * Check if the key exists as a sub key in the value of each array element. 
    */ 
    foreach($array as $value) { 

     if(is_array($value)) { 

      return resolve_key($key, $value); 

     } 

    } 

    /* 
    * Return NULL if no key was found or throw an exception. 
    */ 
    return null; 

} 

이 재귀를 사용합니다. 요청 된 키가 제공된 배열의 첫 번째 수준에 있는지 먼저 확인합니다. 그렇지 않으면 배열 인 각 배열 값에 대해 함수를 한 번 더 실행하십시오.

다음과 같은 클래스 속성의 사용과 같은 키를 찾을 수있을하려면이 도움이

public function __get($key) { 

    return $this->resolve_key($key, $this->internal_array); 

} 

희망.

+0

$ instance-> someKeyFromArray 같은 구문을 원할 것입니다. 이것이 가능한가? – aFreshMelon

+0

배열에 "하위 키"가 있으므로 필요한 논리가 더 복잡합니다. 그러나 당신은'__get ($ key)'매직 메소드를 사용하여 배열을 구현하고 키를'$ class-> key'로 액세스 할 수 있습니다. 논리 자체에 대한 제안으로 내 대답을 업데이트하려고 노력할 것입니다. 지금까지 뭐 해봤 어? – AnotherGuy

+0

맞아,이게 내가하려는거야. 나는 __get ($ key)를 사용하고있다. 나는 단지 배열에서 키를 찾는 방법을 찾고 있는데, 이는 $ this-> data [$ key]를 반환하는 것이 아니라 그 것이 도움이되지 않기 때문이다. 내 키는 모두 고유 한 이름입니다. – aFreshMelon

1

다음은 아주 간단한 예제 구현 :

// sample class 
class A { 

    // the data array 
    protected $data = array(); 

    // init 
    public function __construct($data = null) { 
    $this->setData($data); 
    } 

    // recursive search of a key 
    private function searchLayer($key, $layer, $searchKey) { 
    // return the layer if we have a match 
    if ((string) $key === (string) $searchKey) return $layer; 

    // loop the array if we need to go deeper 
    if ((array) $layer === $layer) { 
     foreach ($layer as $k => $v) { 
      // apply recursition 
      $result = $this->searchLayer($k, $v, $searchKey); 

      // return on match 
      if (!empty($result)) return $result; 
     } 
    } 

    // nothing found - recursion ended here 
    return null; 
    } 

    // returns the value of the data array with the given key 
    public function getValueByKey($searchKey) { 
    echo '<br>search by key: ' . $searchKey . '<br>'; 

    // check if we have a match 
    foreach ($this->data as $key => $layer) { 
     // resolve layer 
     $result = $this->searchLayer($key, $layer, $searchKey); 

     // return on match 
     if (!empty($result)) return $result; 
    } 

    // nothing found 
    return null; 
    } 

    // set the data 
    public function setData($data) { 
    if ((array) $data === $data) $this->data = $data; 
    } 

    // possible extension 
    public function __get($key) { 
    return $this->getValueByKey($key); 
    } 
} 

// create the object of the class 'a' 
$a = new A(); 

// set the data 
$a->setData(array(
    'value1', 
    'key2' => 'value2', 
    'key3' => array(
    'subkey31' => 'value31', 
    'subkey32' => 'value32' 
) 
)); 

var_dump($a->getValueByKey('subkey32')); 
var_dump($a->subkey32); 

출력 : 여기 string(7) "value32" string(7) "value32"

테스트를 : http://writecodeonline.com/php 그냥 코드와 공격 실행을 붙여 넣습니다.

편집

은 물론 이것은 매우 기본적인 예이다 - 다른 사람이 이미 예를 ArrayAccess에 대해 말했듯이 당신은 또한 주어진 PHP - 클래스의 일부를 사용할 수 있습니다.

+0

$ a-> subkey32가 작동하지 않는 것처럼 보일 것입니다. 물론 $ a-> subkey31과 동일합니다. 그러나 이것은 필수적입니다. – aFreshMelon

+0

이제 괜찮습니다. –

+0

이 방법이 귀하의 목적에 부합한다면 그 대답을 받아 들일 수 있습니다. 그렇지 않으면 무엇을 바꾸고 싶은지 말해주십시오. 고맙습니다. –