【问题标题】:How to search an array of associative arrays with multiple required needles and return the indexes?如何搜索具有多个所需针的关联数组并返回索引?
【发布时间】:2019-01-15 22:03:41
【问题描述】:

我正在尝试搜索关联数组的数组并获取满足所有搜索条件的子数组的键。

这是我的例子:

$list = [
['name' => 'this is items name',
'number' =>  1,
'description' => 'this is description',
'id' => 'just some id',],

 ['name' => 'this is items name2',
'number' =>  1,
'description' => 'this is description2',
'id' => 'just some id',],

 ['name' => 'this is items name3',
'number' =>  1,
'description' => 'this is',
'id' => 'just some id',],
];

我想搜索“this description”并获取如下数组的键:

Array ( [0] => 0 [1] => 1 )

我试过这个:

$array_key = array_keys(array_column($list, 'description'), 'this description', false);

但它仅在搜索词与值完全匹配时才找到键。我该如何解决这个问题?

更准确地说,我如何不仅搜索列描述,还搜索整个数组?

【问题讨论】:

  • 认为带有自定义搜索功能的array_filter可以帮你解决问题
  • 您想要实现什么样的搜索?某种相似度百分比?
  • 我认为您可以使用strpos 函数循环遍历数组和搜索。或者您可以使用array_search 进行搜索,但它会搜索所有值,而不仅仅是描述。

标签: php arrays search multidimensional-array filtering


【解决方案1】:

我将您的问题解释为:如何通过在给定子数组中的所有值中搜索多个针字符串(所有这些字符串都是必需的)来搜索多维数组,并返回每个符合条件的子数组的索引。

我的解决方案通过将子数组数据压缩为单个字符串以迭代方式进行检查来寻求直接结果。一旦一个子数组被认为“不合格”,循环就会被引导到处理下一个子数组以获得最高效率。

*注意,如果您特别需要进行“整个单词”匹配,则需要使用带有单词边界的正则表达式。

如果您不熟悉continue 的作用,这里是link to the manual

代码:(Demo)

$qualifiers = [];
$needles = explode(" ", "this description");

foreach ($list as $index => $set) {
    $smashed = implode($set);
    foreach ($needles as $needle) {
        // echo "\n$smashed";
        if (strpos($smashed, $needle) === false) {
            continue 2;
        }
    }
    $qualifiers[] = $index;
}
var_export($qualifiers);

输出:

array (
  0 => 0,
  1 => 1,
)

附言如果您正在处理来自数据库查询的结果集,那么在查询中执行过滤任务会更好/更直接,因为这样您就可以避免生成一个包含您不想要的数据的结果集。

【讨论】:

    【解决方案2】:

    您可以使用带有正则表达式的foreachpreg_match 来匹配this 直到第一次出现description,方法是匹配任意字符一次或多次非贪婪.*?

    \bthis.*?description

    $result = [];
    foreach ($list as $key => $value) {
        if (preg_match('/\bthis.+?description/', $value["description"])) {
            $result[$key] = $key;
        }
    }
    
    print_r($result);
    

    Demo

    【讨论】:

      【解决方案3】:

      我不太确定你想要什么,但我想这可能是一个很好的起点:

      <?php
      
      $list = [
          [
              'name' => 'this is items name',
              'number' =>  1,
              'description' => 'this is description',
              'id' => 'just some id'
          ],
      
           [
               'name' => 'this is items name2',
              'number' =>  1,
              'description' => 'this is description2',
              'id' => 'just some id'
          ],
      
          'test' => [
               'name' => 
               'this is items name3',
              'number' =>  1,
              'description' => 'do not find this one',
              'id' => 'just some id'
          ],
          'preserve_this_key_please' => [
               'name' => 
               'this is items name4',
              'number' =>  1,
              'description' => 'this is something, key preserved',
              'id' => 'just some id'
          ],    
      ];
      function getKeysBy($array, $key, $value){
          return array_keys(array_filter($array,function($val) use ($key,$value) {
              //return $val[$key] === $value;//exact match
              return strpos($val[$key], $value) === 0;
          } ));
      }
      var_dump(getKeysBy($list, 'description', 'this is'));
      

      输出:

      array(3) {
        [0]=>
        int(0)
        [1]=>
        int(1)
        [2]=>
        string(24) "preserve_this_key_please"
      }
      

      工作代码:

      https://3v4l.org/Gs3He

      注意:在此示例中,键被保留,即如果键是最后一项中的字符串。如果你不需要,那么array_column + friends就足够了。

      【讨论】:

        【解决方案4】:

        你可以以这三种情况为出发点:

        $list=[
        ['name' => 'this is items name',
        'number' =>  1,
        'description' => 'this is description',
        'id' => 'just some id',],
        
         ['name' => 'this is items name2',
        'number' =>  1,
        'description' => 'this is description2',
        'id' => 'just some id',],
        
         ['name' => 'this is items name3',
        'number' =>  1,
        'description' => 'this is',
        'id' => 'just some id',],
        ];
        
        $search='this description';
        //first type of search : any of the word containing in the needle sentence
        $regex='#'.implode('|',preg_split('#\s#',$search)).'#';
        $array_key = array_keys(preg_grep($regex,array_column($list, 'description')));
        print_r($array_key);
        
        //second type of search : all of the words containing in the needle sentence
        $array_key=[];
        $needles=preg_split('#\s#',$search);
        $count_needles=count($needles);
        $regex='#'.implode('|',$needles).'#';
        foreach(array_column($list,'description') as $k=>$v){
            if(preg_replace($regex,'###',$v,-1,$count)){
                if($count===$count_needles) $array_key[]=$k;
            }
        }
        
        print_r($array_key);
        
        //third type of search : based on similarity percentage 
        
        $thereshold=50.0;
        $array_key=[];
        $needles=preg_split('#\s#',$search);
        $count_needles=count($needles);
        $regex='#'.implode('|',$needles).'#';
        foreach(array_column($list,'description') as $k=>$v){
            if(preg_replace($regex,'###',$v,-1,$count)){
                if(min($count,$count_needles)/max($count,$count_needles)*100>$thereshold) $array_key[]=$k;
            }
        }
        
        print_r($array_key);
        

        输出:

        Array
        (
            [0] => 0
            [1] => 1
            [2] => 2
        )
        Array
        (
            [0] => 0
            [1] => 1
        )
        Array
        (
            [0] => 0
            [1] => 1
        )
        

        【讨论】:

          猜你喜欢
          • 2015-08-21
          • 1970-01-01
          • 1970-01-01
          • 2013-02-19
          • 2017-11-27
          • 1970-01-01
          • 1970-01-01
          • 2023-03-06
          • 2019-11-15
          相关资源
          最近更新 更多