映射两个数组的自定义函数,其中一个是子集以检查它们是否存在

Custom function to map two arrays of which one is subset to check if those exist

Note: To the downvoter and to those who need further clarification...

I am trying to get to a solution, to not walk through the loop. i.e., I don't wanna use foreach function.

抱歉这个疯狂的标题。我想要实现的是,我有两个数组,比如:

$full = array("Apple", "Orange", "Mango", "Guava", "Tomato");
$user = array("Apple", "Orange", "Tomato");

我得到它作为 JSON,我使用 json_decode() 将它从 JSON 转换为数组。现在我的问题是,我想将这个输入用于我的函数,returns 我是这样的:

$userSelection = array(
    "Apple" => true,
    "Orange" => true,
    "Mango" => false,
    "Guava" => false,
    "Tomato" => true
);

为此,我可以这样做:

function userSelection ($full, $user)
{
    $final = array();
    foreach ($full as $fruit)
        if (in_array($fruit, $user))
            $final[$fruit] = true;
        else
            $final[$fruit] = false;
    return $final;
}

为了压缩几位,我用了这个。

function userSelection ($full, $user)
{
    $final = array();
    foreach ($full as $fruit)
        $final[$fruit] = in_array($fruit, $user);
    return $final;
}

我的问题是,还有其他更好的方法吗?

您可以使用 array_intersect to find what elements from $user are in $full and/or array_diff 或 $full 中的哪些元素不在 $user

如果对性能分析感兴趣:foreach()是O(N)(把$full里面的每一个元素都打出来),in_array也是O(N)(看$里面的每一个值)用户),因此该循环是最坏情况下的 O(N^2) 操作。如果你有很多水果,那就是性能瓶颈。

您可以通过将 $full 本身变成关联数组来减少它:

$full = array("Apple" => false
      , "Orange" => false
      , "Mango" => false
      , "Guava" => false
      , "Tomato" => false);

然后 userSelection 变为:

function userSelection ($full, $user)
{
    // $full is passed by value (ie copied)
    foreach ($user as $fruit) {
        // check to avoid fruit injection attacks
        if (array_key_exists($fruit, $full))
            { $full[$fruit] = true; }
    return $full;
}

array_key_exists 应该是 O(log N) 或 O(1),这取决于 PHP 的实现,而对于最坏的情况,for 循环仍然是 O(N) O(N*log N) 性能。

当然,您需要很多 水果选项才能看到任何性能优势。