PHP多维数组搜索(按特定值查找键)

Ben*_*uba 103 php search key multidimensional-array

我有这个多维数组.我需要搜索它并只返回匹配"slug"值的键.我知道还有其他关于搜索多维数组的线程,但我并不是真正了解它以适用于我的情况.非常感谢您的帮助!

所以我需要一个像以下的功能:

myfunction($products,'breville-one-touch-tea-maker-BTM800XL');
// returns 1
Run Code Online (Sandbox Code Playgroud)

这是阵列:

$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'    => '',
        ),
);
Run Code Online (Sandbox Code Playgroud)

Aur*_*osa 143

非常简单:

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

  • 如果您在条件语句中使用此函数,则您将要对类型进行绝对检查,因为返回的键有时可能具有[0]的索引.因此,如果进行条件检查,它应该看起来像这样:`if(myfunction($ array,'field','value')!== FALSE))//做某事...... (6认同)
  • 实现最佳性能和技术人员理解的简单解决方案。 (2认同)

Ivá*_*res 135

另一种可能的解决方案是基于该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
Run Code Online (Sandbox Code Playgroud)

说明

该函数array_search()有两个参数.第一个是您要搜索的值.第二个是函数应该搜索的位置.该函数array_column()获取key所在元素的值 'uid'.

摘要

所以你可以用它作为:

array_search('breville-one-touch-tea-maker-BTM800XL', array_column($products, 'slug'));
Run Code Online (Sandbox Code Playgroud)

或者,如果您愿意:

// 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');
Run Code Online (Sandbox Code Playgroud)

原始示例(通过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"
      },...
]
Run Code Online (Sandbox Code Playgroud)

我运行搜索测试100次,搜索名称字段的不同值,然后我计算平均时间(以毫秒为单位).在这里你可以看到一个例子.

结果是在这个答案上提出的方法需要大约2E-7来找到值,而接受的答案方法需要大约8E-7.

就像我之前所说的那样,对于使用这种大小的数组的应用程序而言,两次都是非常好的.如果尺寸增长很多,让我们说1M元素,那么这个小差异也会增加.

更新II

我已经为这个方法添加了一个测试,array_walk_recursive其中提到了一些答案.得到的结果是正确的.如果我们专注于性能,它会比测试中检查的其他人差一点.在测试中,您可以看到它比基于的方法慢大约10倍array_search.同样,对于大多数应用程序而言,这不是非常相关的差异.

更新III

感谢@mickmackusa发现了这种方法的一些限制:

  • 此方法将在关联键上失败.
  • 此方法仅适用于索引子数组(从0开始并具有连续的升序键).

  • 使用`array_search()`和`array_column()`将无法在OP的示例数组上工作,因为子数组键从`1`开始.此方法也会在关联键上失败.此方法仅适用于索引子数组(从"0"开始并具有连续的升序键).这是因为`array_column()`将在其返回的数组中生成新索引. (3认同)

小智 14

此类方法可以通过多个条件在数组中搜索:

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);
Run Code Online (Sandbox Code Playgroud)

会产生:

array(2) {
  [5]=>
  array(2) {
    ["foo"]=>
    string(5) "test4"
    ["bar"]=>
    string(4) "baz1"
  }
  [10]=>
  array(2) {
    ["foo"]=>
    string(5) "test4"
    ["bar"]=>
    string(4) "baz1"
  }
}
Run Code Online (Sandbox Code Playgroud)