使用函数查找不同数组的哪些键相交


Find which keys of separate arrays intersect using a function

我有两个数组,一个是包含数据的输入数组,比如

$array1 = ["_token" => "62d46d4h6dfh841df8h", "sku62" => "3e", "name62" => "meh", "sku61" => "3e", "name61" => "mah", "sku64" => "3e", "name64" => "moh"]

另一个只保存id: $array2 = [64, 74, 61]

编辑清楚:$array1是一个片段的输入从一个post请求,即$array1 = $request->all();的数字在这个数组的键是唯一的Id的附加在表单生成,以区分行与多个表单元素。

每一行都有一个"更新"复选框,也附带一个唯一的id。当勾选此id时,该id将显示在请求中,例如update64。

$array2是通过对请求执行查询来填充的,识别更新字符串并隔离id:

foreach ($array1 as $id => $value) {
     $idInt = filter_var($id, FILTER_SANITIZE_NUMBER_INT);
     $str = preg_replace('/[0-9]+/', '', $id);
     if ($str === "update") {
         array_push($array2, $idInt);
     }
}

我想要一个解决方案,从$array1中返回的元素,在$array2中发现附加的id。

我自己的尝试是这样的:

$relevant_keys = function($key1, $key2) {
            return ((preg_replace('/[0-9]+/', '', $key1) === $key2)) ? 1 : -1;
        };
        $filtered = array_intersect_ukey($array1, array_flip($array2), $relevant_keys);

然而,$filtered返回空,如果我在函数中dd($key2),它甚至没有从$array2返回一个元素,我从$array1得到一些东西,所以这让我感到困惑。

感谢您的帮助。

以下是您发布的确切问题的解决方案:

$filtered = [];
foreach ($array1 as $key => $value)
{
    if ( ! preg_match('/('d+)$/', $key, $matches)) continue;
    if ( ! isset($matches[1]) || ! in_array($matches[1], $array2)) continue;
     $filtered[$key] = $value;
}

但我不确定你处理这件事是否正确。这个输入看起来很可疑

你确定没有更好的方法来格式化请求吗?

根据您的编码尝试,我有一些重要的见解与您分享。

  1. array_intersect_ukey() 应该是他的任务的完美函数调用,但是唉,它不是。我来告诉你为什么。

    • array_intersect_ukey()array_intersect_uassoc()array_uintersect_uassoc()一样,因为内部算法在遇到第一个合格键后将停止寻找其他合格键。我第一次意识到这个现实是在这里。
    • 此外,您声明和使用自定义函数参数($key1$key2)的方式表明您认为$key1始终与第一个指定数组相关,而$key2始终与第二个指定数组相关。这是不正确的,我已经看到许多开发者有同样的错误印象。事实是,在底层,提供给自定义函数的两个参数可能来自任何一个数组。
  2. 基于#1的原因,我建议您将注意力转移到array_filter()上。通过建立包含白名单键和键过滤的查找数组,您可以快速过滤数据。在回调中,我使用trim()删除最后id号之前的字母。这只是在每个键的末尾隔离整数的一种方法。

代码(演示):

$lookup = array_flip($array2);
var_export(
    array_filter(
        $array1,
        fn($key) => isset($lookup[ltrim($key, 'a..z')]),
        ARRAY_FILTER_USE_KEY
    )
);
输出:

array (
  'sku61' => '3e',
  'name61' => 'mah',
  'sku64' => '3e',
  'name64' => 'moh',
)