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*为空。(这将适用于像
    ['c1'=>'a','c2'=>'B','c3'=>'Z']
    这样的上下文,并返回2)
  • 如果不存在,则返回所在行的索引 1个字符串匹配,其余两个c*s为空。(这将适用于像
    ['c1'=>'a','c2'=>'Y','c3'=>'Z']
    这样的上下文,并返回1)
  • 如果不存在,则返回所有三个c*s都为空的行的索引。(这将适用于像
    ['c1'=>'X','c2'=>'Y','c3'=>'Z']
    这样的上下文,并返回0)
我知道我的数组中可能有一些条目理论上返回超过1个索引,但这可以通过创建基数组的方式排除


我开始了很多尝试,结果都是用了很多意大利面嵌套的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

如果使用数组差异关联检查进行循环,您尝试了什么?