PHP多维数组按值搜索


332

我有一个要在其中搜索uid并获取数组键的数组。

例子

假设我们有以下二维数组:

$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)(第一个用户的uid)应返回0

函数调用search_by_uid(40489)应返回2

我尝试进行循环,但是我想要更快的执行代码。


有趣的是,下划线(和破折号)库将此函数添加到javascript ...
ErichBSchulz 2014年

9
我编写了一个脚本来测试一些答案的性能。它生成一个50万个成员的数组,并在数组中搜索最后一个成员中的值。我将接受的答案之类的功能与两个array_column单行答案进行了比较。我修改了它们全部以返回实际发现的数组,而不仅仅是键,因为通常这是我的用例。对于每种方法,该函数方法在1000次运行中的平均微延迟得分分别为0.361,search-col 0.184和key-col 0.189。
乔什

Answers:


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

这将起作用。您应该这样称呼它:

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

重要的是要知道,如果你使用的是很重要的===运营商相比,类型必须完全相同,在这个例子中,你必须寻找string或只是使用==代替===

基于angoru的答案。在更高版本的PHP(>= 5.5.0)中,您可以使用单线。

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

这是文档:http : //php.net/manual/zh/function.array-column.php


8
您也应该能够在不使用PHP 5.5的情况下使用array_map代替array_column在一个内衬中执行此操作。只需替换array_column($userdb, 'uid')array_map(function($v){return $v['uid'];},$userdb)
Jesse Green

1
是的,你是对的。Lambda函数自PHP 5.3起可用。更好的是array_search,不是吗?
雅各布·特鲁内切克(JakubTruneček)2016年

@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,则可以使用此backport,谢谢ramsey!

更新:我一直在做一些简单的基准测试,结果列表似乎是最快的,甚至比Jakub自定义函数还快!


如果我正在搜索的值(在此示例中为40489)出现了一次以上,并且我想获取它出现的所有键怎么办?
Dimitris Papageorgiou 2015年

如果值40489出现更多,则该函数一旦在数组中将返回键数组... ?? @angoru
鸡山2015年

如果将第二种情况用于多个结果,则会得到一个键数组。
angoru 2015年

2
当$ userdb中的键未以0,1,2等开头时,这对我不起作用。说该键为1234,4566等。array_search之后的结果键始终为0,1,2,依此类推。在
Kaushtuv '16

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数组,因为我只需要搜索一个特定的数组,但是您可以轻松地添加它。

同样,在我的情况下,由于其他字段可能不是唯一的,因此可能有多个键要返回。

 /**
     * @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)发现第二个例子说明你另一个值(true)的另一关联键(使用)被发现,并返回所有匹配(钥匙里的人与名字使用“泰勒” AND)。

/**
 * @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

@Shihas我更新了答案,我相信它将得到解决。
BEJGAM SHIVA PRASAD

9

我修改了以下描述函数array_search的示例之一。函数searchItemsByKey通过多维数组中的$ key返回所有值(N个级别)。也许,这对某人有用。例:

 $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的另一个原因...更易于Google搜索和查找我自己的代码或我记得的东西。.为自己的公共存储库+1
2015年

顺便说一句,您将结果设置为null,然后在代码中将其与进行比较false
塔哈·帕克苏

更正为返回false,但是在检查布尔值的情况下使用null可能会更好
愤怒的84年

3

我想检查以下数组中的tha $arr,子数组中是否存在“ abc”

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

那我可以用这个

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

我认为这是最简单的定义方式


1

我必须使用un函数来查找数组中的每个元素。因此,我修改了JakubTruneč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

上述代码的帮助之一可以从2D数组的任何列中找到任何(部分匹配)数据,因此可以根据需要查找用户ID
sandeep sharma 2015年

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;
 }

例如,数组中的值为“欢迎来到纽约!”。而您想要的只是“纽约”的第一审!


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 '';
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.