检查一个集合是否包含另一个集合?
Check if a collection contain another 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
的成本相同
你要的是union集合功能
它合并了集合并为您提供了一个独特的结果子集。这意味着删除了重复项。这样你就不必检查一个是否存在于另一个中,只需要你有一个具有唯一值的集合。
阅读有关联合函数的更多信息here
编辑:因为我误解了原文的意图这里是一个更符合意图的答案。
$found = [];
$selectedItems->contains(function ($value, $key) use ($found){
if($orders->contains($value)) {
$found += [$key => $value]
}
})
$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;
我采用了与您不同的方法来检查 $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"],
];
但是您可以使用方法 toArray()
轻松地将 collection
转换为数组,正如我在代码中评论的那样。
然后最终执行并验证结果。
checkContainsOrders($selectedItems, $orders);
此代码已在此处测试:https://3v4l.org/JlCC8
$matched = $selectedItems->intersect($orders)->count() == $selectedItems->count();
相交 returns 在订单中找到的所选项目的集合。
当此交集的计数 == selectedItems 的计数时,我们知道所有 selectedItems 都在相交的集合中(因此所有 selectedItems 都在订单中)。
$selectedItems->diff($orders)->isEmpty();
这将区分第二个集合和第一个集合,如果结果为空,您可以确定您的所有项目都存在于另一个集合中。
使用 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
你要的是union集合功能
它合并了集合并为您提供了一个独特的结果子集。这意味着删除了重复项。这样你就不必检查一个是否存在于另一个中,只需要你有一个具有唯一值的集合。
阅读有关联合函数的更多信息here
编辑:因为我误解了原文的意图这里是一个更符合意图的答案。
$found = [];
$selectedItems->contains(function ($value, $key) use ($found){
if($orders->contains($value)) {
$found += [$key => $value]
}
})
$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;
我采用了与您不同的方法来检查 $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"],
];
但是您可以使用方法 toArray()
轻松地将 collection
转换为数组,正如我在代码中评论的那样。
然后最终执行并验证结果。
checkContainsOrders($selectedItems, $orders);
此代码已在此处测试:https://3v4l.org/JlCC8
$matched = $selectedItems->intersect($orders)->count() == $selectedItems->count();
相交 returns 在订单中找到的所选项目的集合。 当此交集的计数 == selectedItems 的计数时,我们知道所有 selectedItems 都在相交的集合中(因此所有 selectedItems 都在订单中)。
$selectedItems->diff($orders)->isEmpty();
这将区分第二个集合和第一个集合,如果结果为空,您可以确定您的所有项目都存在于另一个集合中。