1

I have the following array:

$array = [  
    ['id' => 1, 'code' => '342'],
    ['id' => 2, 'code' => '765'],
    ['id' => 3, 'code' => '134'],
    ['id' => 1, 'code' => '999'],
];

Here Array[0]['id'] and Array[3]['id'] are duplicates with respect to ['id']. I want to remove one of them (doesn't matter which).

Actually I thought I found a solution with this code:

//data
$row = $stmt->fetchALL(PDO::FETCH_ASSOC); 

$ids = array();
for($i = 0;$i < count($row); $i++ )
{
    if (in_array($row[$i]['id'], $ids))
        {
            unset($row[$i]);
            continue;
        }

    $ids[] = $row[$i]['id'];

}

print_r($row);

For some reason it works well with small arrays, but if I have a lot of values in it with multiple duplicates, it fails. Any suggestion to what I am missing?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Hans Pede
  • 89
  • 1
  • 9

3 Answers3

1

I think this can be done without looping. Let me show an example:

$rows = array (
    array ('id' => 1, 'code' => '342'),
    array ('id' => 2, 'code' => '765'),
    array ('id' => 3, 'code' => '134'),
    array ('id' => 1, 'code' => '342')
);

$input = array_map("unserialize", array_unique(array_map("serialize", $rows)));

echo '<pre>';
print_r($input);

Output:

 Array
 (
  [0] => Array
    (
        [id] => 1
        [code] => 342
    )

  [1] => Array
    (
        [id] => 2
        [code] => 765
    )

  [2] => Array
    (
        [id] => 3
        [code] => 134
    )

  )
Indrasis Datta
  • 8,692
  • 2
  • 14
  • 32
  • thanks for feedback, actually I missed something in the question, damn, Sorry ! I need to point out it is not a complete duplicate (wow, I was sleeping). It is only 'id' that is the duplicate or `$row[$i]['id']` in my example – Hans Pede Jul 10 '16 at 07:08
  • The sample data in the question was edited to better represent the project data after this answer was posted. This answer no longer work as desired with the OP's changed data. – mickmackusa Feb 09 '22 at 14:12
1

Simple solution using regular foreach loop:

$rows = [
    ['id' => 1, 'code' => '342'],
    ['id' => 2, 'code' => '765'],
    ['id' => 3, 'code' => '134'],
    ['id' => 1, 'code' => '342']
];

$ids = [];
foreach ($rows as $k => $item) {
    if (in_array($item['id'], $ids)){
         unset($rows[$k]);            
    } else {
         $ids[] = $item['id'];
    }    
}

print_r($rows);
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
0

I want to remove one of them (doesn't matter which).

Okay, use array_column() to assign temporary first level keys using the id values. Because PHP will not allow two elements in the same level to share the same key, each subsequent duplicate will overwrite the earlier encountered row. Wrap that call in array_values() to remove the temporary keys (re-index the array).

Code: (Demo)

var_export(
    array_values(array_column($rows, null, 'id'))
);

Output:

array (
  0 => 
  array (
    'id' => 1,
    'code' => '999',
  ),
  1 => 
  array (
    'id' => 2,
    'code' => '765',
  ),
  2 => 
  array (
    'id' => 3,
    'code' => '134',
  ),
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136