programing

PHP 다차원 배열 검색(특정 값으로 키 찾기)

sourcetip 2023. 1. 10. 21:43
반응형

PHP 다차원 배열 검색(특정 값으로 키 찾기)

이 다차원 배열이 있습니다.검색하여 "slug" 값과 일치하는 키만 반환해야 합니다.다차원 어레이 검색에는 다른 스레드가 있지만, 제 상황에 적용할 수 있을 만큼 잘 이해하지 못합니다.도와주셔서 정말 감사합니다!

그래서 다음과 같은 기능이 필요합니다.

myfunction($products,'breville-one-touch-tea-maker-BTM800XL');
// returns 1

어레이는 다음과 같습니다.

$products = array (
1  => array(
        'name'          => 'The Breville One-Touch Tea Maker',
        'slug'          => 'breville-one-touch-tea-maker-BTM800XL',
        'shortname'     => 'The One-Touch Tea Maker',
        'listprice'     => '299.99',
        'price'         => '249.99',
        'rating'        => '9.5',
        'reviews'       => '81',
        'buyurl'        => 'http://www.amazon.com/The-Breville-One-Touch-Tea-Maker/dp/B003LNOPSG',
        'videoref1'     => 'xNb-FOTJY1c',
        'videoref2'     => 'WAyk-O2B6F8',
        'image'         => '812BpgHhjBML.jpg',
        'related1'      => '2',
        'related2'      => '3',
        'related3'      => '4',
        'bestbuy'       => '1',
        'quote'         => '',
        'quoteautor'    => 'K. Martino',
        ),

2  => array(
        'name'          => 'Breville Variable-Temperature Kettle BKE820XL',
        'slug'          => 'breville-variable-temperature-kettle-BKE820XL',
        'shortname'     => 'Variable Temperature Kettle',
        'listprice'     => '199.99',
        'price'         => '129.99',
        'rating'        => '9',
        'reviews'       => '78',
        'buyurl'        => 'http://www.amazon.com/Breville-BKE820XL-Variable-Temperature-1-8-Liter-Kettle/dp/B001DYERBK',
        'videoref1'     => 'oyZWBD83xeE',
        'image'         => '41y2B8jSKmwL.jpg',
        'related1'      => '3',
        'related2'      => '4',
        'related3'      => '5',
        'bestbuy'       => '1',
        'quote'         => '',
        'quoteautor'    => '',
        ),
);

하나의 은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」array_search()기능.PHP 5.5.0 이상을 사용해야 합니다.

$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'
        )
);

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

echo ("The key is: ".$key);
//This will output- The key is: 2

설명.

The function `array_search()` has two arguments. The first one is the value that you want to search. The second is where the function should search. The function `array_column()` gets the values of the elements which key is `'uid'`.

요약

So you could use it as:
array_search('breville-one-touch-tea-maker-BTM800XL', array_column($products, 'slug'));

또는 원하는 경우:

// define function
function array_search_multidim($array, $column, $key){
    return (array_search($key, array_column($array, $column)));
}

// use it
array_search_multidim($products, 'slug', 'breville-one-touch-tea-maker-BTM800XL');

원본 예(xfoxawy 기준)는 DOCS에서 찾을 수 있습니다.
array_column() 페이지를 엽니다.


갱신하다

Vael을 하기 위해 .array_search★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

1000개의 어레이를 포함하는 어레이를 작성했습니다.구조는 다음과 같습니다(모든 데이터는 랜덤화되었습니다).

[
      {
            "_id": "57fe684fb22a07039b3f196c",
            "index": 0,
            "guid": "98dd3515-3f1e-4b89-8bb9-103b0d67e613",
            "isActive": true,
            "balance": "$2,372.04",
            "picture": "http://placehold.it/32x32",
            "age": 21,
            "eyeColor": "blue",
            "name": "Green",
            "company": "MIXERS"
      },...
]

이름 필드의 다른 값을 검색하여 검색 테스트를 100회 실행한 후 평균 시간을 밀리초 단위로 계산했습니다.여기서 예를 볼 수 있습니다.

그 결과 이 답변에 제안된 방법은 값을 구하는 데 약 2E-7이 필요했고, 수용된 답변 방법은 약 8E-7이 필요했다.

앞서 말씀드린 바와 같이 이 크기의 어레이를 사용하는 애플리케이션에서는 두 번 모두 매우 민감합니다.사이즈가 많이 커지면, 예를 들어 100만 요소라고 하면, 이 작은 차이도 커집니다.

업데이트 II

방법에 array_walk_recursive여기 몇 가지 답변에 언급되어 있습니다.결과는 정확합니다.그리고 퍼포먼스에 초점을 맞추면 다른 사람들이 테스트한 것보다 조금 더 나빠요.이 테스트에서는 다음 테스트에 기초한 방법보다 10배 정도 느리다는 것을 알 수 있습니다.array_search이 점은 대부분의 어플리케이션에서 그다지 관련이 없는 차이입니다.

갱신 III

@mickmackusa가 이 방법의 몇 가지 제한을 발견해 준 덕분입니다.

  • 이 메서드는 관련 키에서 실패합니다.
  • 이 메서드는 인덱스된 서브어레이에서만 작동합니다(0부터 시작하여 연속적으로 오름차순 키를 사용).

업데이트 III에 관한 주의사항

  • 퍼포먼스는 고려하지 않습니다.array_keys & array_column과 함께 array_column을 사용하면 다음과 같은1줄로 이 제한을 극복할 수 있습니다.
$product_search_index = 
array_search( 'breville-one-touch-tea-maker-BTM800XL', array_filter( array_combine( array_keys($products), array_column( $products, 'slug' ) ) ) );

매우 심플:

function myfunction($products, $field, $value)
{
   foreach($products as $key => $product)
   {
      if ( $product[$field] === $value )
         return $key;
   }
   return false;
}

이 클래스 메서드는 여러 조건으로 배열에서 검색할 수 있습니다.

class Stdlib_Array
{
    public static function multiSearch(array $array, array $pairs)
    {
        $found = array();
        foreach ($array as $aKey => $aVal) {
            $coincidences = 0;
            foreach ($pairs as $pKey => $pVal) {
                if (array_key_exists($pKey, $aVal) && $aVal[$pKey] == $pVal) {
                    $coincidences++;
                }
            }
            if ($coincidences == count($pairs)) {
                $found[$aKey] = $aVal;
            }
        }

        return $found;
    }    
}

// Example:

$data = array(
    array('foo' => 'test4', 'bar' => 'baz'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test1', 'bar' => 'baz3'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test',  'bar' => 'baz4'),
    array('foo' => 'test4', 'bar' => 'baz1'),
    array('foo' => 'test',  'bar' => 'baz1'),
    array('foo' => 'test3', 'bar' => 'baz2'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test4', 'bar' => 'baz1')
);

$result = Stdlib_Array::multiSearch($data, array('foo' => 'test4', 'bar' => 'baz1'));

var_dump($result);

작성 예정:

array(2) {
  [5]=>
  array(2) {
    ["foo"]=>
    string(5) "test4"
    ["bar"]=>
    string(4) "baz1"
  }
  [10]=>
  array(2) {
    ["foo"]=>
    string(5) "test4"
    ["bar"]=>
    string(4) "baz1"
  }
}

다음 기능을 사용합니다.

function searchThroughArray($search,array $lists){
        try{
            foreach ($lists as $key => $value) {
                if(is_array($value)){
                    array_walk_recursive($value, function($v, $k) use($search ,$key,$value,&$val){
                        if(strpos($v, $search) !== false )  $val[$key]=$value;
                    });
            }else{
                    if(strpos($value, $search) !== false )  $val[$key]=$value;
                }

            }
            return $val;

        }catch (Exception $e) {
            return false;
        }
    }

기능을 호출합니다.

print_r(searchThroughArray('breville-one-touch-tea-maker-BTM800XL',$products));
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; 
} 

나는 아래와 같이 하고 싶다.$products는 첫 번째 문제에서 제시된 실제 배열입니다.

print_r(
  array_search("breville-variable-temperature-kettle-BKE820XL", 
  array_map(function($product){return $product["slug"];},$products))
);

이거 드셔보세요

function recursive_array_search($needle,$haystack) {
        foreach($haystack as $key=>$value) {
            $current_key=$key;
            if($needle==$value['uid'] OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
                return $current_key;
            }
        }
        return false;
    }

다음 방문자의 경우: 재귀 배열 워크를 사용하십시오. 다차원 배열의 모든 "리프"를 방문합니다.영감을 얻으려면 다음과 같이 하십시오.

function getMDArrayValueByKey($a, $k) {
    $r = [];
    array_walk_recursive ($a, 
                          function ($item, $key) use ($k, &$r) {if ($key == $k) $r[] = $item;}
                          );
    return $r;
}

어레이를 JSON으로 변환하고 문자열로 검색한 후 발견된 개체를 반환할 수 있으므로 아무리 깊이 중첩되어 있어도 빠르게 찾을 수 있습니다.

function findObjectByKeyValue($array, $key, $value){
    $object = [];
    $string = json_encode($array);
    $foundPosition = strpos($string, '"' . $key . '":"' . $value . '"');

    if( $foundPosition ){
        $prevBracketPos = strrpos(substr($string, 0, $foundPosition), '{');

        if( $prevBracketPos ){
            $nextBracketPos = strpos($string, '}', $foundPosition);

            if( $nextBracketPos ){
                $brackets = 0;

                while( strpos(substr($string, $foundPosition, $nextBracketPos - $foundPosition), '{') &&
                        substr_count(substr($string, $foundPosition, $nextBracketPos - $foundPosition), '{') > $brackets
                    ){
                    $lenToAdd = strlen(substr($string, $foundPosition, $nextBracketPos - $foundPosition + 1));
                    $nextBracketPos = strpos($string, '}', $foundPosition + $lenToAdd);
                    $brackets++;
                }

                $substr = substr($string, $prevBracketPos, $nextBracketPos - $prevBracketPos + 1);

                // Confirm it's wrapped with brackets before we decode
                if( substr($substr, 0, 1) === '{' && substr($substr, -1, 1) === '}' ){
                    $object = json_decode($substr, true);
                }
            }
        }
    }

    return $object;
}

예:

$arr = [{
    "items":
    {
        "1": [
        {
            "id": "621eaf06062cd",
            "nestedItem":
            {
                "id": "123",
                "nestedItem":
                {
                    "id": "456",
                    "nestedItem":
                    {
                        "id": "789"
                    }
                }
            }
        }],
        "2": [
        {
            "id": "621eb58de7364",
        }],
        "3": [
        {
            "id": "62226910716af",
        }]
    }
}];
echo findObjectByKeyValue($arr, 'id', '123');
/* {
    "id": "123",
    "nestedItem":
    {
        "id": "456",
        "nestedItem":
        {
            "id": "789"
        }
    }
} /*
echo findObjectByKeyValue($arr, 'id', '621eaf06062cd');
/* {
    "id": "621eaf06062cd",
    "nestedItem":
    {
        "id": "123",
        "nestedItem":
        {
            "id": "456",
            "nestedItem":
            {
                "id": "789"
            }
        }
    }
} */

u가 직면할 수 있는 유일한 문제는 배열 내에 문자열로 괄호가 있는지 여부입니다.

연관지을 수 있는 어레이에서는 정상적으로 동작합니다.

public function getKeyByParamValue(string $param, mixed $value, array $array): mixed
{
    $keys = $this->getKeysByParamValue($param, $value, $array);

    return empty($keys) ? null : $keys[0];
}

public function getKeysByParamValue(string $param, mixed $value, array $array): ?array
{
    return array_keys(
        array_combine(
            array_keys($array),
            array_column($array, $param)
        ),
        $value
    );
}

언급URL : https://stackoverflow.com/questions/8102221/php-multidimensional-array-searching-find-key-by-specific-value

반응형