복붙노트

PHP의 다차원 배열에서 key => 값으로 검색하는 방법

카테고리 없음

PHP의 다차원 배열에서 key => 값으로 검색하는 방법

키 값 쌍이 다차원 배열에서 발견 된 모든 하위 배열을 빠르게 얻을 수 있습니까? 배열이 얼마나 깊은 지 말할 수 없습니다.

간단한 예제 배열 :

$arr = array(0 => array(id=>1,name=>"cat 1"),
             1 => array(id=>2,name=>"cat 2"),
             2 => array(id=>3,name=>"cat 1")
);

key = name 및 value = "cat 1"을 검색하면 함수가 반환해야합니다.

array(0 => array(id=>1,name=>"cat 1"),
      1 => array(id=>3,name=>"cat 1")
);

나는 함수가 재귀 적으로 가장 깊은 레벨에 도달해야한다고 생각한다.

해결법

  1. ==============================

    1.

    암호:

    function search($array, $key, $value)
    {
        $results = array();
    
        if (is_array($array)) {
            if (isset($array[$key]) && $array[$key] == $value) {
                $results[] = $array;
            }
    
            foreach ($array as $subarray) {
                $results = array_merge($results, search($subarray, $key, $value));
            }
        }
    
        return $results;
    }
    
    $arr = array(0 => array(id=>1,name=>"cat 1"),
                 1 => array(id=>2,name=>"cat 2"),
                 2 => array(id=>3,name=>"cat 1"));
    
    print_r(search($arr, 'name', 'cat 1'));
    

    산출:

    Array
    (
        [0] => Array
            (
                [id] => 1
                [name] => cat 1
            )
    
        [1] => Array
            (
                [id] => 3
                [name] => cat 1
            )
    
    )
    

    효율성이 중요하다면 모든 재귀 호출이 배열을 병합하지 않고 결과를 같은 임시 $ 결과 배열에 저장하도록 다음과 같이 작성할 수 있습니다.

    function search($array, $key, $value)
    {
        $results = array();
        search_r($array, $key, $value, $results);
        return $results;
    }
    
    function search_r($array, $key, $value, &$results)
    {
        if (!is_array($array)) {
            return;
        }
    
        if (isset($array[$key]) && $array[$key] == $value) {
            $results[] = $array;
        }
    
        foreach ($array as $subarray) {
            search_r($subarray, $key, $value, $results);
        }
    }
    

    여기서 중요한 점은 search_r은 네 번째 매개 변수를 값이 아닌 참조로 사용한다는 것입니다. 앰퍼샌드 &는 매우 중요합니다.

    FYI : 이전 버전의 PHP를 사용하는 경우에는 선언 대신 search_r을 호출 할 때 참조 기준 전달 부분을 지정해야합니다. 즉, 마지막 행은 search_r ($ subarray, $ key, $ value, & $ results)이됩니다.

  2. ==============================

    2.

    SPL 버전은 어떻습니까? 그것은 당신에게 타이핑을 줄여 줄 것입니다 :

    // I changed your input example to make it harder and
    // to show it works at lower depths:
    
    $arr = array(0 => array('id'=>1,'name'=>"cat 1"),
                 1 => array(array('id'=>3,'name'=>"cat 1")),
                 2 => array('id'=>2,'name'=>"cat 2")
    );
    
    //here's the code:
    
        $arrIt = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
    
     foreach ($arrIt as $sub) {
        $subArray = $arrIt->getSubIterator();
        if ($subArray['name'] === 'cat 1') {
            $outputArray[] = iterator_to_array($subArray);
        }
    }
    

    훌륭한 점은 기본적으로 동일한 코드가 RecursiveArrayIterator 대신 RecursiveDirectoryIterator를 사용하여 디렉토리를 반복하는 것입니다. SPL은 roxor입니다.

    SPL에 대한 유일한 불만은 웹에서 잘못 문서화되었다는 것입니다. 그러나 여러 PHP 서적, 특히 Pro PHP에 대한 유용한 정보가 있습니다. 그리고 당신은 아마 더 많은 정보를 위해 구글도 할 수 있습니다.

  3. ==============================

    3.

    <?php
    $arr = array(0 => array("id"=>1,"name"=>"cat 1"),
                 1 => array("id"=>2,"name"=>"cat 2"),
                 2 => array("id"=>3,"name"=>"cat 1")
    );
    $arr = array_filter($arr, function($ar) {
       return ($ar['name'] == 'cat 1');
       //return ($ar['name'] == 'cat 1' AND $ar['id'] == '3');// you can add multiple conditions
    });
    
    echo "<pre>";
    print_r($arr);
    
    ?>
    

    참고 : http://php.net/manual/en/function.array-filter.php

  4. ==============================

    4.

    이 답변에 대한 최적화 팁이 필요한 사람을 위해이 업데이트를 게시했습니다. 특히 John Kugelman의 위의 멋진 답변입니다.

    그의 게시 된 함수는 잘 작동하지만 12000 행 결과 집합을 처리하기 위해이 시나리오를 최적화해야했습니다. 이 기능은 영원한 8 초가 걸렸습니다. 모든 기록을 지키기에는 너무 길었습니다.

    검색을 중지하고 일치하는 항목이 발견되면 반환하는 기능이 필요했습니다. 즉, customer_id를 검색하는 경우 resultset에 값이 하나 뿐이지 만 customer_id가 다차원 배열, 우리는 돌아가고 싶다.

    이 기능의 속도 최적화 된 (그리고 훨씬 단순화 된) 버전입니다. 다른 버전과 달리 배열의 깊이는 하나만 처리 할 수 ​​있으며 여러 결과를 병합하지 않고 반복적으로 처리하지 않습니다.

    // search array for specific key = value
    public function searchSubArray(Array $array, $key, $value) {   
        foreach ($array as $subarray){  
            if (isset($subarray[$key]) && $subarray[$key] == $value)
              return $subarray;       
        } 
    }
    

    이것은 12,000 레코드를 1.5 초와 일치시키는 작업을 가져 왔습니다. 여전히 매우 비싸지 만 훨씬 합리적입니다.

  5. ==============================

    5.

    if (isset($array[$key]) && $array[$key] == $value)
    

    빠른 버전의 사소한 개선.

  6. ==============================

    6.

    다차원 배열의 선형 검색 알고리즘 (위의 선형)은 깊이가 전체 배열을 탐색하는 데 필요한 반복 횟수를 늘리면 복잡해 지므로주의하십시오. 예 :

    array(
        [0] => array ([0] => something, [1] => something_else))
        ...
        [100] => array ([0] => something100, [1] => something_else100))
    )
    

    적절한 알고리즘을 사용하여 찾고있는 것을 찾기 위해 최대 200 번 반복합니다 (바늘이 [100] [1]에있는 경우).

    이 경우 선형 알고리즘은 O (n) (전체 배열 요소의 총 주문 수)에서 수행됩니다.이 경우 빈도가 낮기 때문에 바늘 찾기에 백만 개의 항목 (예 : 1000x100x10 배열)이 평균 500,000 회 반복됩니다. 또한 다차원 배열의 구조를 변경하기로 결정한 경우 어떻게됩니까? 그리고 깊이가 100보다 크면 PHP는 재귀 알고리즘을 없애 버립니다. 컴퓨터 과학은 더 잘할 수 있습니다.

    가능한 경우 항상 다차원 배열 대신 객체를 사용하십시오.

    ArrayObject(
       MyObject(something, something_else))
       ...
       MyObject(something100, something_else100))
    )
    

    사용자 정의 비교기 인터페이스와 함수를 적용하여 정렬하고 찾습니다.

    interface Comparable {
       public function compareTo(Comparable $o);
    }
    
    class MyObject implements Comparable {
       public function compareTo(Comparable $o){
          ...
       }
    }
    
    function myComp(Comparable $a, Comparable $b){
        return $a->compareTo($b);
    }
    

    uasort ()를 사용하여 사용자 정의 콤퍼레이터를 활용할 수 있습니다. 객체를 정렬하고 관리 할 수있는 고유 한 컬렉션을 구현해야합니다 (항상 ArrayObject를 확장하여 검색 기능을 최소한 포함합니다).

    $arrayObj->uasort("myComp");
    

    일단 이들이 정렬되면 (uasort는 O (n log n)입니다. 이것은 임의의 데이터를 얻는 것만큼이나 좋습니다) 바이너리 검색은 O (log n) 시간에 작업을 수행 할 수 있습니다. 즉, 백만 항목 만 ~ 20 회 반복됩니다. 수색. 필자는 맞춤형 비교기 바이너리 검색이 PHP (array_search ()가 해당 속성이 아닌 객체 참조에서 작동하는 자연 순서 지정을 사용)에서 구현되지 않는다는 것을 알고 있기 때문에 내가하는 것처럼이 자체를 구현해야합니다.

    이 방법은 객체가 정렬 방법을 정의하므로 코드를 무한대로 재활용 할 수 있으므로 더 효율적 (더 이상 깊이가 없음)하고 더 중요하게 보편적입니다 (인터페이스를 사용하여 비교 가능성을 적용한다고 가정). 훨씬 더 =)

  7. ==============================

    7.

    $result = array_filter($arr, function ($var) {   
      $found = false;
      array_walk_recursive($var, function ($item, $key) use (&$found) {  
        $found = $found || $key == "name" && $item == "cat 1";
      });
      return $found;
    });
    
  8. ==============================

    8.

    http://snipplr.com/view/51108/nested-array-search-by-value-or-key/

    <?php
    
    //PHP 5.3
    
    function searchNestedArray(array $array, $search, $mode = 'value') {
    
        foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $key => $value) {
            if ($search === ${${"mode"}})
                return true;
        }
        return false;
    }
    
    $data = array(
        array('abc', 'ddd'),
        'ccc',
        'bbb',
        array('aaa', array('yyy', 'mp' => 555))
    );
    
    var_dump(searchNestedArray($data, 555));
    
  9. ==============================

    9.

    function in_multi_array($needle, $key, $haystack) 
    {
        $in_multi_array = false;
        if (in_array($needle, $haystack))
        {
            $in_multi_array = true; 
        }else 
        {
           foreach( $haystack as $key1 => $val )
           {
               if(is_array($val)) 
               {
                   if($this->in_multi_array($needle, $key, $val)) 
                   {
                       $in_multi_array = true;
                       break;
                   }
               }
            }
        }
    
        return $in_multi_array;
    } 
    
  10. ==============================

    10.

    비슷한 것을 필요로했지만 다차원 배열을 값으로 검색하려면 ... John 예제를 사용하고

    function _search_array_by_value($array, $value) {
            $results = array();
            if (is_array($array)) {
                $found = array_search($value,$array);
                if ($found) {
                    $results[] = $found;
                }
                foreach ($array as $subarray)
                    $results = array_merge($results, $this->_search_array_by_value($subarray, $value));
            }
            return $results;
        }
    

    나는 그것이 누군가를 돕기를 바란다 :)

  11. ==============================

    11.

    이것은 John K.가 게시 한 개정 된 기능입니다. 배열의 특정 키만 가져오고 그 위에는 아무것도 넣지 않아도됩니다.

    function search_array ( $array, $key, $value )
    {
        $results = array();
    
        if ( is_array($array) )
        {
            if ( $array[$key] == $value )
            {
                $results[] = $array;
            } else {
                foreach ($array as $subarray) 
                    $results = array_merge( $results, $this->search_array($subarray, $key, $value) );
            }
        }
    
        return $results;
    }
    
    $arr = array(0 => array(id=>1,name=>"cat 1"),
           1 => array(id=>2,name=>"cat 2"),
           2 => array(id=>3,name=>"cat 1"));
    
    print_r(search_array($arr, 'name', 'cat 1'));
    
  12. ==============================

    12.

    해결책은 다음과 같습니다.

    <?php
    $students['e1003']['birthplace'] = ("Mandaluyong <br>");
    $students['ter1003']['birthplace'] = ("San Juan <br>");
    $students['fgg1003']['birthplace'] = ("Quezon City <br>");
    $students['bdf1003']['birthplace'] = ("Manila <br>");
    
    $key = array_search('Delata Jona', array_column($students, 'name'));
    echo $key;  
    
    ?>
    
  13. ==============================

    13.

    값이있는 배열 요소에서 키 값을 반환하는 다른 버전 (재귀가없고 속도에 맞게 최적화 됨) :

    // if the array is 
    $arr['apples'] = array('id' => 1);
    $arr['oranges'] = array('id' => 2);
    
    //then 
    print_r(search_array($arr, 'id', 2);
    // returns Array ( [oranges] => Array ( [id] => 2 ) ) 
    // instead of Array ( [0] => Array ( [id] => 2 ) )
    
    // search array for specific key = value
    function search_array($array, $key, $value) {
      $return = array();   
      foreach ($array as $k=>$subarray){  
        if (isset($subarray[$key]) && $subarray[$key] == $value) {
          $return[$k] = $subarray;
          return $return;
        } 
      }
    }
    

    여기에 올린 모든 분들께 감사드립니다.

  14. ==============================

    14.

    function findKey($tab, $key){
        foreach($tab as $k => $value){ 
            if($k==$key) return $value; 
            if(is_array($value)){ 
                $find = findKey($value, $key);
                if($find) return $find;
            }
        }
        return null;
    }
    
  15. from https://stackoverflow.com/questions/1019076/how-to-search-by-key-value-in-a-multidimensional-array-in-php by cc-by-sa and MIT lisence