값으로 PHP 다차원 배열 검색


332

검색 uid하고 배열의 키를 얻으려는 배열이 있습니다.

다음과 같은 2 차원 배열이 있다고 가정합니다.

$userdb = array(
    array(
        'uid' => '100',
        'name' => 'Sandra Shush',
        'pic_square' => 'urlof100'
    ),
    array(
        'uid' => '5465',
        'name' => 'Stefanie Mcmohn',
        'pic_square' => 'urlof100'
    ),
    array(
        'uid' => '40489',
        'name' => 'Michael',
        'pic_square' => 'urlof40489'
    )
);

함수 호출 search_by_uid(100)(첫 번째 사용자의 UI)은을 반환해야합니다 0.

함수 호출 search_by_uid(40489)은을 반환해야합니다 2.

루프를 만들려고했지만 더 빠른 코드 실행을 원합니다.


흥미롭게도 밑줄 (및 낮은 대시) 라이브러리는이 기능을 자바 스크립트에 추가합니다.
ErichBSchulz

9
몇 가지 답변의 성능을 테스트하는 스크립트를 작성했습니다. 500k 멤버 배열의 배열을 생성하고 마지막 멤버의 값을 검색합니다. 나는 수용 된 답변과 같은 기능을 두 개의 array_column원 라이너 답변 과 비교했습니다 . 일반적으로 내 유스 케이스이기 때문에 키뿐만 아니라 실제 발견 된 배열을 반환하도록 모두 수정했습니다. 기능 방법은 각 방법에 대해 0.361, search-col 0.184 및 keys-col 0.189 평균 마이크로 지연을 1000 회 실행했습니다.
Josh

답변:


474
function searchForId($id, $array) {
   foreach ($array as $key => $val) {
       if ($val['uid'] === $id) {
           return $key;
       }
   }
   return null;
}

작동합니다. 다음과 같이 호출해야합니다.

$id = searchForId('100', $userdb);

===연산자 비교 유형을 사용하는 경우 정확히 동일한 유형이어야 한다는 것을 알아야합니다 .이 예에서는 검색 string하거나 ==대신 사용해야 합니다 ===.

앙 고루 답변을 기반으로 합니다. 이후 버전의 PHP ( >= 5.5.0)에서는 하나의 라이너를 사용할 수 있습니다.

$key = array_search('100', array_column($userdb, 'uid'));

여기 문서입니다 : http://php.net/manual/en/function.array-column.php .


8
또한 array_column 대신 array_map을 사용하여 하나의 라이너에서 PHP 5.5 없이이 작업을 수행 할 수 있어야합니다. 그냥 교체 array_column($userdb, 'uid')와 함께array_map(function($v){return $v['uid'];},$userdb)
제시 녹색

1
네, 그렇습니다. Lambda 함수는 PHP 5.3부터 사용할 수 있습니다. 그리고 더 낫지 array_search않습니까?
Jakub Truneček

@angoru 나는 ​​원래 솔루션 ( foreach루프)이 일치하는 것을 발견하자마자 멈추기 때문에 더 빨리 수행 할 것이라고 생각합니다 . 새로운 솔루션은 전체 배열을 한 번 반복하여 추출 array_column한 다음 두 번째 루프를 반복하여 검색을 수행해야합니다 (일치하는 것을 찾을 때까지). 새로운 솔루션은 더 읽기 쉽고 간결하지만 OP는 특히 성능 문제를 일으켰습니다.
BeetleJuice

@ JakubTruneček. 질문에 주어진 동일한 배열과 관련이 있습니다. id를 전달하여 배열에서 사용자 이름을 원합니다. findUserName (40489) 함수는 'Michael'을 반환해야합니다. 어떻게 가능합니까?
Ashok Gujjar

@ JakubTruneček 안녕 내 코드 에서이 문제에 직면했지만 꽤 다른 것이 있습니다. 필자의 경우 'uid'값이 여러 번 존재하므로 설립 된 키 배열을 가져와야합니다.
Bhavin Thummar

314

(PHP 5> = 5.5.0)을 사용하는 경우이 작업을 수행하기 위해 고유 한 기능을 작성할 필요가 없습니다.이 행을 작성하면됩니다.

하나의 결과 만 원하는 경우 :

$key = array_search(40489, array_column($userdb, 'uid'));

여러 결과

$keys = array_keys(array_column($userdb, 'uid'), 40489);

주석에 표시된 연관 배열이있는 경우 다음을 사용하여 만들 수 있습니다.

$keys = array_keys(array_combine(array_keys($userdb), array_column($userdb, 'uid')),40489);

PHP <5.5.0을 사용하는 경우 램지 덕분 에이 백 포트를 사용할 수 있습니다 !

업데이트 : 간단한 벤치 마크를 작성했으며 여러 결과 형식이 Jakub 사용자 정의 기능보다 훨씬 빠릅니다.


검색중인 값 (이 예제에서는 40489 임)이 한 번 이상 나타나고 나타나는 모든 키를 얻으려면 어떻게해야합니까?
Dimitris Papageorgiou

40489 값이 배열에 두 번 이상 나타나면 함수는 키 배열을 반환합니다 ... ?? @angoru
jishan

여러 결과에 대해 두 번째 경우를 사용하면 키 배열이 생깁니다.
angoru

2
$ userdb의 키가 0,1, 2 등으로 시작하지 않고 키가 1234,4566 등이라고 말하면 작동하지 않습니다. array_search 이후의 결과 키는 항상 0,1,2입니다. 에
Kaushtuv

1
이것은 연관 배열에서는 작동하지 않지만 다음과 같이 해결할 수 있습니다. array_search(40489, array_combine(array_keys($userdb), array_column($userdb, 'uid')))
John Mellor

32

이후 버전의 PHP (> = 5.5.0)에서는이 단일 라이너를 사용할 수 있습니다.

$key = array_search('100', array_column($userdb, 'uid'));

array_column 결과를 특정 변수에 넣으면 배열의 각 결과에 대해 array_column이 호출되지 않습니다.
Maykonn

26

Jakub의 훌륭한 답변을 바탕으로 , uid뿐만 아니라 키를 지정할 수있는보다 일반적인 검색이 있습니다.

function searcharray($value, $key, $array) {
   foreach ($array as $k => $val) {
       if ($val[$key] == $value) {
           return $k;
       }
   }
   return null;
}

용법: $results = searcharray('searchvalue', searchkey, $array);


이것은 매우 도움이됩니다.이 솔루션을 사용하여 문제를 해결할 수 있다고 생각하지만 여전히 문제가 있습니다. 통찰력을 제공 할 수 있습니까? 문제는 여기에서 찾을 수 있습니다 : stackoverflow.com/questions/28704644/...
jasenmp의

19

나는 이것이 이미 답변되었다는 것을 알고 있지만, 이것을 사용하고 코드에서 조금 더 확장하여 uid로만 검색하지 않았습니다. 해당 기능이 필요한 다른 사람과 공유하고 싶습니다.

여기 내 예가 있으며 이것이 첫 번째 대답이라는 것을 명심하십시오. 하나의 특정 배열 만 검색하면 되었기 때문에 param 배열을 가져 왔지만 쉽게 추가 할 수있었습니다. 본질적으로 uid 이상으로 검색하고 싶었습니다.

또한 내 상황에서는 고유하지 않을 수있는 다른 필드로 검색 한 결과 반환 할 여러 키가있을 수 있습니다.

 /**
     * @param array multidimensional 
     * @param string value to search for, ie a specific field name like name_first
     * @param string associative key to find it in, ie field_name
     * 
     * @return array keys.
     */
     function search_revisions($dataArray, $search_value, $key_to_search) {
        // This function will search the revisions for a certain value
        // related to the associative key you are looking for.
        $keys = array();
        foreach ($dataArray as $key => $cur_value) {
            if ($cur_value[$key_to_search] == $search_value) {
                $keys[] = $key;
            }
        }
        return $keys;
    }

나중에 다른 값과 연관 키를 검색 할 수 있도록 이것을 작성했습니다. 따라서 첫 번째 예에서는 특정 연관 키에서 값을 검색하고 모든 일치 항목을 반환 할 수 있습니다.

값 ( '테일러') 어떤 연관 키 (FIRST_NAME)에서 발견되는이 두 번째 예를 보여줍니다 당신 다른 값 (사실은) 다른 연관 키 (고용)에서 발견하고, 모든 일치 (키 반환되는 경우 이름을 가진 사람 '테일러'가 사용됩니다).

/**
 * @param array multidimensional 
 * @param string $search_value The value to search for, ie a specific 'Taylor'
 * @param string $key_to_search The associative key to find it in, ie first_name
 * @param string $other_matching_key The associative key to find in the matches for employed
 * @param string $other_matching_value The value to find in that matching associative key, ie true
 * 
 * @return array keys, ie all the people with the first name 'Taylor' that are employed.
 */
 function search_revisions($dataArray, $search_value, $key_to_search, $other_matching_value = null, $other_matching_key = null) {
    // This function will search the revisions for a certain value
    // related to the associative key you are looking for.
    $keys = array();
    foreach ($dataArray as $key => $cur_value) {
        if ($cur_value[$key_to_search] == $search_value) {
            if (isset($other_matching_key) && isset($other_matching_value)) {
                if ($cur_value[$other_matching_key] == $other_matching_value) {
                    $keys[] = $key;
                }
            } else {
                // I must keep in mind that some searches may have multiple
                // matches and others would not, so leave it open with no continues.
                $keys[] = $key;
            }
        }
    }
    return $keys;
}

기능 사용

$data = array(
    array(
        'cust_group' => 6,
        'price' => 13.21,
        'price_qty' => 5
    ),
    array(
        'cust_group' => 8,
        'price' => 15.25,
        'price_qty' => 4
    ),
    array(
        'cust_group' => 8,
        'price' => 12.75,
        'price_qty' => 10
    )
);

$findKey = search_revisions($data,'8', 'cust_group', '10', 'price_qty');
print_r($findKey);

결과

Array ( [0] => 2 ) 

10

외모는 array_filter 이 적합한 솔루션이 될 것입니다 ...

$userdb=Array
(
    (0) => Array
        (
            (uid) => '100',
            (name) => 'Sandra Shush',
            (url) => 'urlof100'
        ),

    (1) => Array
        (
            (uid) => '5465',
            (name) => 'Stefanie Mcmohn',
            (pic_square) => 'urlof100'
        ),

    (2) => Array
        (
            (uid) => '40489',
            (name) => 'Michael',
            (pic_square) => 'urlof40489'
        )
);

PHP 코드

<?php 
$search = 5465;
$found = array_filter($userdb,function($v,$k) use ($search){
  return $v['uid'] == $search;
},ARRAY_FILTER_USE_BOTH) // With latest PHP third parameter is mandatory.. Available Values:- ARRAY_FILTER_USE_BOTH OR ARRAY_FILTER_USE_KEY  

$values= print_r(array_value($found)); 
$keys =  print_r(array_keys($found)); 

@ BEJAM SHIVA PRASAD이 stackoverflow.com/questions/44721195/… 와 함께 나를 도울 수 있습니까?
Valay

syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ';'
Shihas

어떤 라인과 코드 및 배열 구조를 의미하는지 더 많은 정보를 붙여 넣을 수 있습니까?
BEJGAM SHIVA PRASAD

@시 답변을 업데이트했습니다. 해결 될 것입니다.
BEJGAM SHIVA PRASAD

9

설명 함수 array_search 아래 예제 중 하나를 수정 했습니다 . 함수 searchItemsByKey는 다차원 배열 (N 레벨)에서 $ key로 모든 값을 반환합니다. 아마도 누군가에게 유용 할 것입니다. 예:

 $arr = array(
     'XXX'=>array(
               'YYY'=> array(
                    'AAA'=> array(
                          'keyN' =>'value1'
                   )
               ),
              'ZZZ'=> array(
                    'BBB'=> array(
                          'keyN' => 'value2'
                   )
               )
              //.....
           )
);


$result = searchItemsByKey($arr,'keyN');

print '<pre>';
print_r($result);
print '<pre>';
// OUTPUT
Array
(
  [0] => value1
  [1] => value2
)

기능 코드 :

function searchItemsByKey($array, $key)
{
   $results = array();

  if (is_array($array))
  {
    if (isset($array[$key]) && key($array)==$key)
        $results[] = $array[$key];

    foreach ($array as $sub_array)
        $results = array_merge($results, searchItemsByKey($sub_array, $key));
  }

 return  $results;
}

7

여기에 하나의 라이너가 있습니다.

$pic_square = $userdb[array_search($uid,array_column($userdb, 'uid'))]['pic_square'];

3

이것은 오래된 질문이며 받아 들일 수있는 대답이 있지만, 받아 들인 대답에 한 가지 변경 사항을 제안 할 것이라고 생각했습니다. 따라서 먼저 수락 된 답변이 여기에 정확하다는 데 동의합니다.

function searchArrayKeyVal($sKey, $id, $array) {
   foreach ($array as $key => $val) {
       if ($val[$sKey] == $id) {
           return $key;
       }
   }
   return false;
}

사전 설정 'uid'를 대신 함수의 매개 변수로 바꾸면 이제 아래 코드를 호출하면 여러 배열 유형에서 하나의 함수를 사용할 수 있습니다. 작은 변화이지만 약간의 차이가 있습니다.

    // Array Data Of Users
$userdb = array (
    array ('uid' => '100','name' => 'Sandra Shush','url' => 'urlof100' ),
    array ('uid' => '5465','name' => 'Stefanie Mcmohn','url' => 'urlof100' ),
    array ('uid' => '40489','name' => 'Michael','url' => 'urlof40489' ),
);

// Obtain The Key Of The Array
$arrayKey = searchArrayKeyVal("uid", '100', $userdb);
if ($arrayKey!==false) {
    echo "Search Result: ", $userdb[$arrayKey]['name'];
} else {
    echo "Search Result can not be found";
}

PHP 바이올린 예제


내가 SOF를 사용하는 또 다른 이유는 ... 구글에 쉽게 내 자신의 코드 또는 내가 기억하는 것을 찾을 수 .. 내 자신의 공공 저장소 +1
화가 84

BTW, 결과를로 설정 null한 다음 코드에서와 비교하고 false있습니다.
Taha Paksu 2016 년

대신 false를 반환하여 수정되었지만 부울을 확인하는 경우 null이 더 좋을 수 있습니다.
Angry 84

3

$arr하위 배열에 'abc'가 있는지 여부는 다음 배열에서 확인하고 싶습니다.

$arr = array(
    array(
        'title' => 'abc'
    )
);

그런 다음 이것을 사용할 수 있습니다

$res = array_search('abc', array_column($arr, 'title'));
if($res == ''){
    echo 'exists';
} else {
    echo 'notExists';
}

이것이 가장 간단한 정의 방법이라고 생각합니다.


1

배열의 모든 요소를 ​​찾는 un 함수를 사용해야했습니다. 그래서 Jakub Truneček이 수행 한 기능을 다음과 같이 수정했습니다.

function search_in_array_r($needle, $array) {
    $found = array();
    foreach ($array as $key => $val) {
        if ($val[1] == $needle) {
            array_push($found, $val[1]);
        }
    }
    if (count($found) != 0)
        return $found;
    else
        return null;
}

1
/**
 * searches a simple as well as multi dimension array
 * @param type $needle
 * @param type $haystack
 * @return boolean
 */
public static function in_array_multi($needle, $haystack){
    $needle = trim($needle);
    if(!is_array($haystack))
        return False;

    foreach($haystack as $key=>$value){
        if(is_array($value)){
            if(self::in_array_multi($needle, $value))
                return True;
            else
               self::in_array_multi($needle, $value);
        }
        else
        if(trim($value) === trim($needle)){//visibility fix//
            error_log("$value === $needle setting visibility to 1 hidden");
            return True;
        }
    }

    return False;
}

1

이 기능을 사용할 수 있습니다. https://github.com/serhatozles/ArrayAdvancedSearch

<?php 
include('ArraySearch.php');

$query = "a='Example World' and b>='2'";

$Array = array(
'a' => array('d' => '2'),
array('a' => 'Example World','b' => '2'),
array('c' => '3'), array('d' => '4'),
);

$Result = ArraySearch($Array,$query,1);

echo '<pre>';
print_r($Result);
echo '</pre>'; 

// Output:
// Array
// (
//    [0] => Array
//        (
//            [a] => Example World
//            [b] => 2
//        )
//
// )

1
$a = ['x' => ['eee', 'ccc'], 'b' => ['zzz']];

$found = null;
$search = 'eee';

array_walk($a, function ($k, $v) use ($search, &$found) {
    if (in_array($search, $k)) {
        $found = $v;
    }
});

var_dump($found);

1

이 시도

<?php
 function recursive_array_search($needle,$haystack) {
    foreach($haystack as $key=>$value) {
        $current_key=$key;
        if($needle===$value OR (is_array($value) && 
            recursive_array_search($needle,$value) !== false)) {
             return $current_key;
        }
    }
    return false;
 }
 ?>

1

공유 만하면 좋을 것 같습니다.

if( ! function_exists('arraySearchMulti')){
function arraySearchMulti($search,$key,$array,$returnKey=false)
{
    foreach ($array as $k => $val) {
        if (isset($val[$key])) {
            if ((string)$val[$key] == (string)$search) {
                return ($returnKey ? $k : $val);
            }
        }else{
            return (is_array($val) ? arraySearchMulti($search,$key,$val,$returnKey) : null);
        }
    }
    return null;
}}

0

이것도 시도

function search_in_array($srchvalue, $array)
{
    if (is_array($array) && count($array) > 0)
    {
        $foundkey = array_search($srchvalue, $array);
        if ($foundkey === FALSE)
        {
            foreach ($array as $key => $value)
            {
                if (is_array($value) && count($value) > 0)
                {
                    $foundkey = search_in_array($srchvalue, $value);
                    if ($foundkey != FALSE)
                        return $foundkey;
                }
            }
        }
        else
            return $foundkey;
    }
}

0
for( $i =0; $i < sizeof($allUsers); $i++)
    {   
    $NEEDLE1='firstname';
    $NEEDLE2='emailAddress';
    $sterm='Tofind';
     if(isset($allUsers[$i][$NEEDLE1]) && isset($allUsers[$i][$NEEDLE2])
        {
            $Fname= $allUsers[$i][$NEEDLE1];
            $Lname= $allUsers[$i][$NEEDLE2];

            $pos1 = stripos($Fname, $sterm);
            $pos2=stripos($Lname, $sterm);//not case sensitive 

            if($pos1 !== false ||$pos2 !== false)
            {$resultsMatched[] =$allUsers[$i];}
            else
            {   continue;}              
        }

}
Print_r($resultsMatched); //will give array for matched values even partially matched

위의 코드를 사용하면 2D 배열의 모든 열에서 (일부 일치하는) 데이터를 찾을 수 있으므로 문제에 따라 사용자 ID를 찾을 수 있습니다.


이것이 왜 질문에 대한 대답인지 설명하는 문구를 추가하십시오
Lorenz Meyer

사용자 ID가 발견 될 수 있도록 문제에 필요한 전술 한 코드의 엉 도움 2D 어레이에있는 열의 임의의 (부분적으로 일치하는) 데이터를 찾을 수있다
샌딥 샤르마

0

@mayhem 함수를 확장하면이 예제는 검색 문자열의 일부 ( 대부분 ) 와 일치시키려는 경우 "퍼지"검색에 더 가깝습니다 .

 function searchArrayKeyVal($sKey, $id, $array) {
    foreach ($array as $key => $val) {
        if (strpos(strtolower($val[$sKey]), strtolower(trim($id))) !== false) {
            return $key;
        }
    }
         return false;
 }

예를 들어 배열의 값은 Welcome to New York!입니다. "New York!"의 첫 번째 사례를 원했습니다.


0
$search1 = 'demo';
$search2 = 'bob';
$arr = array('0' => 'hello','1' => 'test','2' => 'john','3' => array('0' => 'martin', '1' => 'bob'),'4' => 'demo');
foreach ($arr as $value) { 
    if (is_array($value)) { 
        if (in_array($search2, $value)) { 
            echo "successsfully";    
            //execute your code 
        }
    } else {  
        if ($value == $search1) { 
            echo "success";
        }
    }
 }

0

질문이 있다면

$a = [
     [
       "_id" => "5a96933414d48831a41901f2",
       "discount_amount" => 3.29,
       "discount_id" => "5a92656a14d488570c2c44a2",
     ],
     [
       "_id" => "5a9790fd14d48879cf16a9e8",
       "discount_amount" => 4.53,
       "discount_id" => "5a9265b914d488548513b122",
     ],
     [
       "_id" => "5a98083614d488191304b6c3",
       "discount_amount" => 15.24,
       "discount_id" => "5a92806a14d48858ff5c2ec3",
     ],
     [
       "_id" => "5a982a4914d48824721eafe3",
       "discount_amount" => 45.74,
       "discount_id" => "5a928ce414d488609e73b443",
     ],
    [
       "_id" => "5a982a4914d48824721eafe55",
       "discount_amount" => 10.26,
       "discount_id" => "5a928ce414d488609e73b443",
     ],
   ];

답변 :

function searchForId($id, $array) {
    $did=0;
    $dia=0;
   foreach ($array as $key => $val) {
       if ($val['discount_id'] === $id) {
           $dia +=$val['discount_amount'];
           $did++;
       }
   }
    if($dia != '') {
        echo $dia;
        var_dump($did);
    }
   return null;
};
print_r(searchForId('5a928ce414d488609e73b443',$a));

0

내 해결책 :

function searchArrayForField($array, $field, $value) {
    $i = 0;
    foreach ($array as &$row) {
        if ($row[$field] === $value) {
            return $i;
        }
        $i++
    }
    return '';
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.