'How to remove from a multidimensional array all duplicate elements including the original?

I am using php 7.1.

I have seen that to eliminate the duplicate elements it is enough with this

array_unique($array, SORT_REGULAR);

I've also seen this work

array_map("unserialize", array_unique(array_map("serialize", $array)));

But that only deletes the elements that are duplicated from the array, I want to delete those that are duplicated but I don't want it to leave me only 1 without a duplicate, I want it to also delete that original on which it has been based to verify that it is duplicated

How could I do it?

For example i have this

$array = array(
    [0] = array(
        [id] => 1,
        [number] => 12345,
        [date] => 2022-05-09
    )
    [1] = array(
        [id] => 2,
        [number] => 123456,
        [date] => 2022-05-09
    )
    [2] = array(
        [id] => 3,
        [number] => 123456,
        [date] => 2022-05-09
    )
    [3] = array(
        [id] => 3,
        [number] => 123456,
        [date] => 2022-05-09
    )
)

How can i let it become this:?

    $array = array(
        [0] = array(
            [id] => 1,
            [number] => 12345,
            [date] => 2022-05-09
        )
        [1] = array(
            [id] => 2,
            [number] => 123456,
            [date] => 2022-05-09
        )
)


Solution 1:[1]

This should be straightforward. Pluck all IDs using array_column and use array_count_values to get counts of occurrences of each ID. Then, use array_filter to filter only unique ones.

<?php

$unique_ids = array_count_values(array_column($array,'id'));
$res = array_filter($array, fn($v) => $unique_ids[$v['id']] === 1);
print_r($res);

Online Demo

Solution 2:[2]

Implementing the advice from How to remove values from an array if occurring more than one time?, for best time complexity, keep a lookup array of previously encountered values and their index. When a value is encountered more than once, delete the current and original row from the input array. It is perfectly safe to call unset() on an element that has already been unset(), no breakage will occur.

I have extended your input array to demonstrate that unset() will not cause trouble. I am using "array destructuring" in the foreach() to make the code more concise.

Code: (Demo)

$array = [
    ['id' => 1, 'number' => 12345, 'date' => '2022-05-09'],
    ['id' => 2, 'number' => 123456, 'date' => '2022-05-09'],
    ['id' => 3, 'number' => 123456, 'date' => '2022-05-09'],
    ['id' => 3, 'number' => 123456, 'date' => '2022-05-09'],
    ['id' => 4, 'number' => 123457, 'date' => '2022-05-10'],
    ['id' => 4, 'number' => 123458, 'date' => '2022-05-11'],
    ['id' => 3, 'number' => 123459, 'date' => '2022-05-12']
];

$found = [];
foreach ($array as $index => ['id' => $id]) {
    if (isset($found[$id])) {
        unset($array[$index], $array[$found[$id]]);
    } else {
        $found[$id] = $index;
    }
}
var_export($array);

Output:

array (
  0 => 
  array (
    'id' => 1,
    'number' => 12345,
    'date' => '2022-05-09',
  ),
  1 => 
  array (
    'id' => 2,
    'number' => 123456,
    'date' => '2022-05-09',
  ),
)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 nice_dev
Solution 2 mickmackusa