对象数组过滤技巧:正确使用 array_filter() 基于特定属性过滤
2024-03-02 12:59:54
使用 array_filter() 过滤拥有特定 id 值的对象
问题概述
在使用 array_filter()
过滤对象数组时,如果你想基于对象的某个属性(例如 warehouse_id
)进行过滤,可能会遇到意想不到的结果。这篇文章将探讨如何正确使用 array_filter()
来解决此问题,并提供一个清晰的代码示例。
解决方案
array_some()
为了在 array_filter()
中基于对象的属性进行过滤,我们可以利用 array_some()
函数。array_some()
接收一个数组和一个回调函数,如果数组中至少一个元素满足回调函数的条件,则返回 true
。
示例代码
$warehouses = [
new Warehouse(1, 100, [1, 2, 3, 4]),
new Warehouse(2, 1100, [1, 2, 3, 4]),
new Warehouse(3, 12000, [1, 2, 3, 4]),
new Warehouse(4, 130000, [1, 2, 3, 4]),
new Warehouse(5, 1400000, [1, 2, 3, 4]),
];
$ifeeds = [
12 => new InventoryFeed(12, 1, "2as21332kjd"),
10 => new InventoryFeed(10, 2, "2123asagfrtsdd"),
11 => new InventoryFeed(11, 3, "2as1231sds2d"),
13 => new InventoryFeed(13, 4, "2as1231sds2d"),
14 => new InventoryFeed(14, 5, "2as1231sds2d"),
];
$warehouses_filtered = array_filter(
$warehouses,
fn($warehouse) => array_some(
$ifeeds,
fn($ifeed) => $ifeed->getWarehouseId() === $warehouse->getId()
)
);
echo count($warehouses_filtered); // 3
改进后的代码
改进后的代码使用箭头函数简化了代码并提高了可读性。
常见问题解答
1. 为什么原始的 array_filter()
无法按预期工作?
原始的 array_filter()
中的匿名函数返回一个布尔值,表示元素是否应该包含在结果数组中。由于内部循环永远不会遇到与当前 warehouse
对象的 id
匹配的 ifeed
元素,因此该匿名函数总是返回 false
,导致过滤后数组为空。
2. array_some()
在这里是如何工作的?
array_some()
遍历 ifeeds
数组,并检查每个元素是否满足条件:$ifeed->getWarehouseId() === $warehouse->getId()
。如果至少一个元素满足此条件,则 array_some()
返回 true
。
3. 为什么使用箭头函数?
箭头函数是一种简洁且更易读的语法,用于编写匿名函数。它们消除了 function
和大括号,并允许使用更简洁的表达式。
4. 是否可以在一个回调函数中使用多个 array_some()
?
可以。你可以根据需要在回调函数中嵌套多个 array_some()
。
5. 如何提高 array_filter()
的性能?
对于大型数组,可以考虑使用 array_map()
和 array_reduce()
等更有效的方法进行过滤。