使用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
的费用
答案 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中)。