如何用多个必需的针头搜索关联数组的数组并返回索引?

时间:2018-08-08 15:10:19

标签: php arrays search multidimensional-array filtering

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

这是我的示例:

$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',],
];

我想搜索“此描述”并获取像这样的数组的键:

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

我尝试过:

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

,但是只有在搜索词与值完全匹配时,它才会找到关键字。我该如何解决这个问题?

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

4 个答案:

答案 0 :(得分:0)

我不确定您想要什么,但是我想这可能是一个不错的起点:

 category | sales | oh
----------+-------+----
 Food     |    35 | 25
 Clothes  |   125 | 20
(2 rows)

输出:

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

工作代码:

https://3v4l.org/Gs3He

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

答案 1 :(得分:0)

您可以使用以下三种情况作为起点:

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

答案 2 :(得分:0)

您可以将foreachpreg_match与正则表达式结合使用,以匹配{* 1}}到this首次出现,方法是匹配任意字符一次或多次非贪婪{ {1}}:

\bthis.*?description

description

Demo

答案 3 :(得分:0)

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

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

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

如果您不熟悉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,
)

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