michael
michael

Reputation: 421

PHP compare 2 different arrays by a value and find differences

I have 2 very completely different arrays:

1 looks like this ($fromBackend):

array:3 [
  114466 => array:1 [
    "BrandID" => 136,
    "record" => 114466
  ]
  114467 => array:1 [
    "BrandID" => 1,
    "record" => 114467
  ]
  114468 => array:1 [
    "BrandID" => 2,
    "record" => 114468
  ]
]

The other one looks like this ($fromFrontend):

array:2 [
  0 => Entity {#920
    #id: 117
    #brandId: 1
  }
  1 => Entity {#915
    #id: 118
    #brandId: 2
  }
]

Now as you can see I need to find the "record" of the first array where the brandId's dont match so in this case I need to find "114466" because BrandId => 136 doesn't exist in the second array

Here's what I've got:

$recordsToDelete = [];
foreach ($fromBackend as $fromBackendItem) {
    foreach ($fromFrontend as $fromFrontendItem) {
        if ($fromBackendItem['BrandID'] !== $brand->getBrandId()) {
            $recordsToDelete[] = $fromBackendItem['record'];
        }
    }
 }

 dd($recordsToDelete);

This gets me a weird results probably cause I am looping too much:

0 => 114466
1 => 114466
2 => 114467
3 => 114468

Upvotes: 0

Views: 38

Answers (1)

Nick
Nick

Reputation: 147146

You're adding every record to your $recordsToDelete array because any time the brandId values don't match, you add the record and, since the brandId values don't match for all records, that means that condition is always true at least once for every record. Instead, compare all the brandId values from the front end for each back end record and only add the record to $recordsToDelete if it doesn't match any other brandId value. For example:

$recordsToDelete = array();
foreach ($fromBackend as $backendItem) {
    foreach ($fromFrontEnd as $frontendItem) {
        if ($frontendItem->brandId == $backendItem['BrandID']) break;
    }
    if ($frontendItem->brandId != $backendItem['BrandID']) $recordsToDelete[] = $backendItem['record'];
}
print_r($recordsToDelete);

Output (for your sample data):

Array
(
    [0] => 114466
)

Demo on 3v4l.org

If $fromFrontEnd could be empty the above code will raise an undefined variable error. You can work around that by checking it using the null coalescing operator e.g.

if (($frontendItem->brandId ?? -1) != $backendItem['BrandID']) $recordsToDelete[] = $backendItem['record'];

or by using an explicit found flag:

foreach ($fromBackend as $backendItem) {
    $found = false;
    foreach ($fromFrontEnd as $frontendItem) {
        if ($frontendItem->brandId == $backendItem['BrandID']) {
            $found = true;
            break;
        }
    }
    if (!$found) $recordsToDelete[] = $backendItem['record'];
}

although it would probably be simpler to just not execute the outer foreach loop unless !empty($fromFrontEnd);

Demo of above 2 solutions on 3v4l.org

Upvotes: 2

Related Questions