检查一个集合是否包含另一个集合?

时间:2018-08-23 19:14:46

标签: php laravel laravel-5 laravel-collection

使用Laravel集合,检查一个集合($selectedItems)是否包含另一个集合($orders)的好方法是什么?

我当前正在使用两个foreach循环$selectedItems,并使用另一个循环检查它是否在$orders中存在。

   $selectedItems = collect([
        ["ItemId" => "T123", "Price" => "12.00"],
        ["ItemId" => "T99", "Price" => "13.00"],
    ]);

    $orders = collect([
        ["ItemId" => "T123", "Cost" => "12.00"],
        ["ItemId" => "T99", "Cost" => "13.00"],
        ["ItemId" => "T33", "Cost" => "13.00"],
    ]);

    $found = [];

    foreach ($selectedItems as $selectedItem)
    {
        foreach($orders as $orderItem)
        {
            if ($orderItem['ItemId'] !== $selectedItem['ItemId']) {
                continue;
            }

            $found[] = $orderItem;
        }
    }


    if (count($found) == $selectedItems->count()) {
        dd("Matched");
    } else {
        dd("Not Matched");
    }

如何还确保$selectedItems的价格与$orders的费用

4 个答案:

答案 0 :(得分:1)

您想要的是联合收集功能。

它将合并集合,并为您提供唯一的结果子集。意味着删除重复项。这样,您不必检查是否存在另一个,只需检查您的集合具有唯一值即可。

详细了解联合功能here

编辑:因为我误解了原著的意图,所以这里的答案更符合意图。

$found = [];
$selectedItems->contains(function ($value, $key) use ($found){
    if($orders->contains($value)) {
        $found += [$key => $value]
    }
})

答案 1 :(得分:0)

$selectedItems = collect([
        ["ItemId" => "T123", "Price" => "12.00"],
        ["ItemId" => "T99", "Price" => "13.00"],
    ]);

    $orders = collect([
        ["ItemId" => "T123", "Cost" => "12.00"],
        ["ItemId" => "T99", "Cost" => "13.00"],
        ["ItemId" => "T33", "Cost" => "13.00"],
    ]);
// get orders and selected items ids as an array
    $ordersIds = array_map('array_shift', $orders->toArray());
    $selectedItemIds = array_map('array_shift', $selectedItems->toArray());
// check selected items ids exist in orders ids    
    $exist = count(array_intersect($selectedItemIds, $ordersIds)) == count($selectedItemIds);
// if exist, return true
    if ($exist)
        return true;

答案 2 :(得分:0)

我采用了与您不同的方法来检查$ orders项目键是否包含在$ selectedItems中。但是我想我得到了预期的结果。

我创建了此函数,包装了仅处理这两个数组的代码。

function checkContainsOrders($selectedItems, $orders)
{
    //Commenting this lines that are necessary only for Laravel Collection
    //$selectedItems = $selectedItems->toArray();
    //$orders = $orders->toArray();

    $selectedItemsKeys = array_column($selectedItems, 'ItemId');
    $orderItemsKeys = array_column($orders, 'ItemId');

    $intersectedValues = array_intersect($selectedItemsKeys, $orderItemsKeys);

    if (count($intersectedValues) === count($selectedItems) || count($intersectedValues) === count($orders)) {
        echo 'yup';
    } else {
        echo 'nope';
    }
}

您会发现我正在使用array_column从两个数组中仅提取我想要的列,并使用array_intersect来查找两者之间的匹配项。

我的数据仅声明为数组:

$selectedItems = [
    ["ItemId" => "T123", "Price" => "12.00"],
    ["ItemId" => "T99", "Price" => "13.00"],
];

$orders = [
    ["ItemId" => "T123", "Cost" => "12.00"],
    ["ItemId" => "T99", "Cost" => "13.00"],
    ["ItemId" => "T33", "Cost" => "13.00"],
];

但是您可以按照我在代码中的注释,使用方法collection轻松地将toArray()转换为数组。

然后最终执行并验证结果。

checkContainsOrders($selectedItems, $orders);

此代码已在此处经过测试:https://3v4l.org/JlCC8

答案 3 :(得分:0)

$matched = $selectedItems->intersect($orders)->count() == $selectedItems->count();

Intersect返回在Orders中找到的selectedItems的集合。 当这个交集的计数== selectedItems的计数时,我们知道所有selectedItems都在相交的集合中(因此所有selectedItems都在Orders中)。