Search code examples
phparrayslaravelduplicatesarray-filter

How to remove duplicate in multidimensional array by comparing two values in each set. using php/laravel


I have an array with vehicle_code and year and vehicle_code repeating for the same year in array. I want to remove if vehicle code and year values repeat in an array. I tried many array function like in_array array_column array_search so on. but all example show how to remove duplicate in 1 column only but I need to compare values for two columns in each set.

  0 => array:2 [
    0 => "AUA3H147"
    1 => 2015
    2 => Audi
    3 => 12457
  ]
  1 => array:2 [
    0 => "AUA3H147"
    1 => 2015
    2 => tata
    3 => 16832545
  ]

  2 => array:2 [
    0 => "AUA3H148"
    1 => 2016
    2 => tata
    3 => 55555
  ]
  3 => array:2 [
    0 => "AUA3H148"
    1 => 2017
    2 => Audi
    3 => 55555
  ]

I need output like the below:

  0 => array:2 [
    0 => "AUA3H147"
    1 => 2015
    2 => Audi
    3 => 12457
  ]
  1 => array:2 [
    0 => "AUA3H148"
    1 => 2016
    2 => tata
    3 => 16832545
  ]
  2 => array:2 [
    0 => "AUA3H148"
    1 => 2017
    2 => tata
    3 => 55555
  ]

I tried like

$newArray = array(); 
$addArrayValues = array(); 
$priceVehicleYearCounter = 0
foreach ( $excelPriceArr as $key => $line ) { 
if ( (!in_array($line[0], $addArrayValues)) && (!in_array($line[1], $addArrayValues)) ) { 
      $addArrayValues[$priceVehicleYearCounter] = array(
      'id' => $priceVehicleYearCounter,
      'vehicle_code' => $line[0],
      'year' => $line[1],
      );
      $priceVehicleYearCounter++;
      $newArray[$priceVehicleYearCounter] = $line; 
   }
}

something like this I saw same example with single column search i modified it to search two values but it didn't work

 if(array_search($line, array_column($addArrayValues, 'vehicle_code','year')) == false) {
                                $addArrayValues[$priceVehicleYearCounter] = array(
                                    'id' => $priceVehicleYearCounter,
                                    'vehicle_code' => $line[0],
                                    'year' => $line[1],
                                );
                                $priceVehicleYearCounter++;
                                $newArray[$priceVehicleYearCounter] = $line;
                            }

also like this:

$result = array_unique($addArrayValues, SORT_REGULAR);

$result = array_map("unserialize", array_unique(array_map("serialize", $addArrayValues)));

sample set in array:

1 => array:12 [
    0 => "AUA3H142"
    1 => 2013
    2 => "AUDI"
    3 => "A3 SPORTBACK"
    4 => "1.8 TFSI AMBITION (01/2011-04/2013)"
    5 => "1.8 TFSI AMBITION"
    6 => 2209
    7 => 500
    8 => 12023
    9 => 125648
    10 => 118835
    11 => "Private"
  ]

Solution

  • Use a composite first-level key when populating the result array. The key must be the combination of the values from the two identifying columns.

    When finished iterating, re-index the array with array_values().

    This is more generally demonstrated here: Filter/Remove rows where column value is found more than once in a multidimensional array

    The null coalescing assignment operator will only store the first occurring data for each composite key.

    Code: (Demo)

    foreach ($array as $row) {
        $compositeKey = $row[0] . '_' . $row[1];
        $result[$compositeKey] ??= $row;      // only store if first occurrence of compositeKey
    }
    var_export(array_values($result));  // re-index and print