Php 如何基于降序准则识别数组中的索引?
我有一个数组,看起来像这样:Php 如何基于降序准则识别数组中的索引?,php,arrays,filtering,Php,Arrays,Filtering,我有一个数组,看起来像这样: [ 0=>['v'=> 1, 'c1'=>null , 'c2'=>null , 'c3'=>null], 1=>['v'=> 2, 'c1'=>'A' , 'c2'=>null , 'c3'=>null], 2=>['v'=> 3, 'c1'=>'A' , 'c2'=>'B' , 'c3'=>null], 3=>['v'=> 4, 'c1'=>'A'
[
0=>['v'=> 1, 'c1'=>null , 'c2'=>null , 'c3'=>null],
1=>['v'=> 2, 'c1'=>'A' , 'c2'=>null , 'c3'=>null],
2=>['v'=> 3, 'c1'=>'A' , 'c2'=>'B' , 'c3'=>null],
3=>['v'=> 4, 'c1'=>'A' , 'c2'=>'B' , 'c3'=> 'C']
]
键c1、c2、c3可以单独用null或任何字符串填充
我以['c1'=>'a','c2'=>'B','c3'=>'C']
的形式获得上下文输入
如何确定最适合输入数组的行索引
“最佳”是指(按降序排列):
- 如果上下文中所有三个字符串(c1、c2、c3)都精确匹配 数组返回这个索引。(在本例中,此规则已应用并返回3)
- 如果这不存在,则返回行的索引,其中2个上下文字符串适合,其余一个c*为空。(这将适用于像
这样的上下文,并返回2)['c1'=>'a','c2'=>'B','c3'=>'Z']
- 如果不存在,则返回所在行的索引
1个字符串匹配,其余两个c*s为空。(这将适用于像
这样的上下文,并返回1)['c1'=>'a','c2'=>'Y','c3'=>'Z']
- 如果不存在,则返回所有三个c*s都为空的行的索引。(这将适用于像
这样的上下文,并返回0)['c1'=>'X','c2'=>'Y','c3'=>'Z']
我开始了很多尝试,结果都是用了很多意大利面嵌套的if-then-else东西,感觉必须有一种更结构化的方法来实现这一点。对于每个搜索案例,您都可以使用自己的适当回调
// $results will contain all of the elements of $values that have ['cX' => 'myValX']
$results = array_filter(
$values, // is your big array in which you want to search
function($value){ // this callback will be called for each element of $values
if($value['c1'] === 'myVal1' AND $value['c2'] === 'myVal2' and $value['c3'] === 'myVal3'){
return true; // to have the match element of $values array to be in the returned array
}
}
);
您想编写自己的函数,可以是
$referenceArray = [
0=>['v'=> 1, 'c1'=>null , 'c2'=>null , 'c3'=>null],
1=>['v'=> 2, 'c1'=>'A' , 'c2'=>null , 'c3'=>null],
2=>['v'=> 3, 'c1'=>'A' , 'c2'=>'B' , 'c3'=>null],
3=>['v'=> 4, 'c1'=>'B' , 'c2'=>'B' , 'c3'=> 'C']
];
function getBest ( $needle, $reference ) {
$myBestIndex = null;
$myBestMetrix = null;
foreach ( $reference as $index => $values ) {
$currentMetrix = 0;
foreach ($values as $key => $value ) {
if (is_null($value)) continue;
if ($value == $needle[$key]) $currentMetrix++;
else {
$currentMetrix = 0;
break;
}
}
if ($currentMetrix >= ($myBestMetrix ?? $currentMetrix) {
$myBestIndex = $index;
$myBestMetrix = $currentMetrix;
}
}
return $myBestIndex;
}
您必须迭代整个数组并计算每行的值。如果需要,可以将这部分代码封装到自定义函数中
$array = [
0 => ['v' => 1, 'c1' => null, 'c2' => null, 'c3' => null],
1 => ['v' => 2, 'c1' => 'A', 'c2' => null, 'c3' => null],
2 => ['v' => 3, 'c1' => 'A', 'c2' => 'B', 'c3' => null],
3 => ['v' => 4, 'c1' => 'B', 'c2' => 'B', 'c3' => 'C']
];
$input = ['c1' => 'B', 'c2' => 'B', 'c3' => 'C'];
$best = null;
array_walk($array, function ($val, $key) use (&$best, $input) {
$cur_value = count(array_intersect_assoc($val, $input));
if (is_null($best) || $cur_value > $best['value']) {
$best = [
'index' => $key,
'value' => $cur_value
];
}
});
print_r($best['index']); //output 3
如果使用数组差异关联检查进行循环,您尝试了什么?