12

I've got a multidimensional array setup like the following:

array(
  [0]=>
  array(
    ["name"]=> "Foo"
    ["slug"]=> "Bar"
  )
  [1]=>
  array(
    ["name"]=> "Foo"
    ["slug"]=> "Bar"
  )
  [2]=>
  array(
    ["name"]=> "Test 1"
    ["slug"]=> "test-1"
  )
  [3]=>
  array(
    ["name"]=> "Test 2"
    ["slug"]=> "test-2"
  )
  [4]=>
  array(
    ["name"]=> "Test 3"
    ["slug"]=> "test-3"
  )
)

What would be the best way to search through the area for duplicates values in "name" and remove them, so that each value in the multidimensional array is unique?

Thanks in advance!

hsatterwhite
  • 7,160
  • 5
  • 26
  • 29
  • 1
    Say you have a duplicate `name` but the `slug` value varies--what are you anticipating the result? (Which duplicate should be removed/deleted?) – Brad Christie Jan 03 '11 at 14:25
  • @Brad Christie, in this particular case the name/slug combo will not vary. Thanks for your comment! :) – hsatterwhite Jan 03 '11 at 14:28
  • This is kind of a wise-ass non-answer, but sometimes it's best not to let duplicates get added in the first place. That is to say, if you happen to be creating this array, rather than getting from some source outside your control, you can test whether your item is already there before appending it. In this case a simple `in_array('some_value', array_column($your_array, 'some_key'))` should get it done. – David Mar 22 '19 at 15:00

6 Answers6

30

You can use an associative array.

$temp_array = array();
foreach ($array as &$v) {
    if (!isset($temp_array[$v['name']]))
        $temp_array[$v['name']] =& $v;
}

This creates a temporary array, using $v['name'] as the key. If there is already an element with the same key, it is not added to the temporary array.

You can convert the associative array back to a sequential array, using

$array = array_values($temp_array);

Example code and output: http://codepad.org/zHfbtUrl

Thai
  • 10,746
  • 2
  • 45
  • 57
  • 1
    I like this, it's a pretty simple and compact means of doing the job. Thanks for your help and providing a link to a working example! :) – hsatterwhite Jan 03 '11 at 15:18
9

Since everyone given alternatives, here's a solution to the problem at-hand. Sometimes we have to work with the data we have, not re-arrange it the way we like it. That being said, this will remove all sub-sequent entries from the array that are duplicates.

$array = Array(
  Array(
    'name'  => 'Test 3',
    'slug'  => 'test-3'
  ),
  Array(
    'name'  => 'Foo',
    'slug'  => 'Bar'
  ),
  Array(
    'name'  => 'Foo',
    'slug'  => 'Bar'
  ),
  Array(
    'name'  => 'Test 1',
    'slug'  => 'test-1'
  ),
  Array(
    'name'  => 'Test 2',
    'slug'  => 'test-2'
  ),
  Array(
    'name'  => 'Test 3',
    'slug'  => 'test-3'
  ),
);
var_dump($array);

for ($e = 0; $e < count($array); $e++)
{
  $duplicate = null;
  for ($ee = $e+1; $ee < count($array); $ee++)
  {
    if (strcmp($array[$ee]['name'],$array[$e]['name']) === 0)
    {
      $duplicate = $ee;
      break;
    }
  }
  if (!is_null($duplicate))
    array_splice($array,$duplicate,1);
}
var_dump($array);

Which will look like this:

array(6) {
  [0]=>
  array(2) {
    ["name"]=>
    string(6) "Test 3"
    ["slug"]=>
    string(6) "test-3"
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(3) "Foo"
    ["slug"]=>
    string(3) "Bar"
  }
  [2]=>
  array(2) {
    ["name"]=>
    string(3) "Foo"
    ["slug"]=>
    string(3) "Bar"
  }
  [3]=>
  array(2) {
    ["name"]=>
    string(6) "Test 1"
    ["slug"]=>
    string(6) "test-1"
  }
  [4]=>
  array(2) {
    ["name"]=>
    string(6) "Test 2"
    ["slug"]=>
    string(6) "test-2"
  }
  [5]=>
  array(2) {
    ["name"]=>
    string(6) "Test 3"
    ["slug"]=>
    string(6) "test-3"
  }
}
array(4) {
  [0]=>
  array(2) {
    ["name"]=>
    string(6) "Test 3"
    ["slug"]=>
    string(6) "test-3"
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(3) "Foo"
    ["slug"]=>
    string(3) "Bar"
  }
  [2]=>
  array(2) {
    ["name"]=>
    string(6) "Test 1"
    ["slug"]=>
    string(6) "test-1"
  }
  [3]=>
  array(2) {
    ["name"]=>
    string(6) "Test 2"
    ["slug"]=>
    string(6) "test-2"
  }
}
Brad Christie
  • 100,477
  • 16
  • 156
  • 200
  • 1
    Thanks for the solution Brad! I like your point of view on taking care of the problem at hand and this works for me. Although I am going to take @Gobs' suggestion of looking in to a hash table, since I've never done so. Good opportunity to learn. :) – hsatterwhite Jan 03 '11 at 15:19
  • 2
    Hey try out this one-liner baby: `$input = array_map('unserialize', array_unique(array_map('serialize', $input)));` https://stackoverflow.com/a/946300/3063226 – Heitor Aug 23 '17 at 08:21
  • 1
    NOTE: When I tried this implementation, it did remove one duplicate. I actually had some values in triplicate, so I repeated the operation, and it did remove again, but I opted for the answer provided in the comments by @Heitor. – Jason Jun 02 '18 at 01:22
  • this wont remove all duplicates but the very first duplicate found only , if there are 3 rows matching the name it wont remove the third row – Muhammad Omer Aslam Sep 16 '19 at 04:19
5
$array = array(
    0 => array(
        "name"=> "Foo",
        "slug"=> "Bar"
    ),
    1 => array(
        "name"=> "Foo",
        "slug"=> "Bar"
    ),
    2 => array(
        "name"=> "Test 1",
        "slug"=> "test-1"
    ),
    3 => array(
        "name"=> "Test 2",
        "slug"=> "test-2"
    ),
    4 => array(
        "name"=> "Test 3",
        "slug"=> "test-3"
    )
);



function array_unique_by_key (&$array, $key) {
    $tmp = array();
    $result = array();
    foreach ($array as $value) {
        if (!in_array($value[$key], $tmp)) {
            array_push($tmp, $value[$key]);
            array_push($result, $value);
        }
    }
    return $array = $result;
}

array_unique_by_key($array, "name");
benomatis
  • 5,536
  • 7
  • 36
  • 59
Alex
  • 161
  • 3
  • 8
1

Just looking at your particular case, I would recommend using a hash table instead of a 2-dimensional array. If you use your "name" as the key in the hash, each entry would be unique.

Is there a specific need for the multidimensional array?

Gobs
  • 11
  • 2
  • Never used a hash table, but I'll certainly look in to it as you suggested. No specific need for the multidimensional array, it's just how I prepared the data at the time. Thanks for your suggestion and help. :) – hsatterwhite Jan 03 '11 at 15:15
0
function multi_array_unique_by_value($array, $colon = '')
{
    $ret_array = array();
    $has_array = array();
    foreach($array as $item)
    { 
        $item_array = (array)$item;
        if(!in_array($item_array[$colon], $has_array))
        {
            array_push($ret_array, $item);
            array_push($has_array, $item_array[$colon]);
        }
    }
    return $ret_array;
}

You can give your array here and give a colon name for making unique.

On this code, you have multidimensonal array, we foreach that array, which column index for us, we pushing that column values. And when same value, its not adding return array.

So this solution for array_unique for 1 coloumn.

Metin Erbek
  • 84
  • 2
  • 8
0

Much simpler solution for your multidimensional array.

$unique = array_map('unserialize', array_unique(array_map('serialize', $array)));

echo "<pre>";
print_r($unique);
manish1706
  • 1,571
  • 24
  • 22
  • 1
    you can also use `array_map("json_decode", array_unique(array_map("json_encode", $final)))` if you are storing data in database. – manish1706 May 25 '17 at 13:40
  • Did we need this copy-pasted duplicate advice? https://stackoverflow.com/a/946300/2943403 Did you mean to vote to close as a duplicate instead of answering this question? – mickmackusa Oct 13 '21 at 07:10