Search code examples
phparraysobjectfilteringintersection

Keep objects in one objectArray which have an id value found in another objectArray


I'm trying to use array_filter() to filter an array of objects, they share a common value which is warehouse_id.

$warehouse_1 = new warehouse(1, 100, [1,2,3,4]);
$warehouse_2 = new warehouse(2, 1100, [1,2,3,4]);
$warehouse_3 = new warehouse(3, 12000, [1,2,3,4]);
$warehouse_4 = new warehouse(4, 130000, [1,2,3,4]);
$warehouse_5 = new warehouse(5, 1400000, [1,2,3,4]);

$inventory_feed_1 = new inventory_feed(12, 1, "2as21332kjd");
$inventory_feed_2 = new inventory_feed(10, 2, "2123asagfrtsdd");
$inventory_feed_3 = new inventory_feed(11, 3, "2as1231sds2d");
$inventory_feed_4 = new inventory_feed(13, 4, "2as1231sds2d");
$inventory_feed_5 = new inventory_feed(14, 5, "2as1231sds2d");

$ifeeds = ["a" => $inventory_feed_1, "b" => $inventory_feed_2, "c" => $inventory_feed_3];
$warehouses = [$warehouse_1, $warehouse_2, $warehouse_3, $warehouse_4, $warehouse_5];

$warehouses_filtered = array_filter(
  $warehouses,
  function ($warehouse) use ($ifeeds) {
    foreach($ifeeds as $ifeed_id => $ifeed) {
      return $ifeed->getWarehouseId() == $warehouse->getId();
  });

echo count($warehouses_filtered);

The desired output should be [$warehouse_1, $warehouse_2, $warehouse_3] but it always returns me the original one (5)


Solution

  • You're returning on the first iteration of the foreach loop, so you're only testing whether the warehouse matches the first feed.

    You should return true as soon as you find a match, but not return false until you get all the way through the loop without finding a match.

    $warehouses_filtered = array_filter(
      $warehouses,
      function ($warehouse) use ($ifeeds) {
        foreach($ifeeds as $ifeed_id => $ifeed) {
          if ($ifeed->getWarehouseId() == $warehouse->getId()) {
            return true;
          }
        }
        return false;
      });
    

    DEMO