1

I want to remove duplicate values from multi-dim array, I tried all the possible solutions which is already described but for me, is not working, can anyone please correct it? Here's my Array:

Array ( 
  [0] => Array ( 
         [0] => element_10 
         [1] => block_1 
         [2] => element_4 
         [3] => element_1 
         [4] => element_3 
               ) 
[1] => Array ( 
        [0] => block_1 
        [1] => block_2 
        [2] => element_8 
        [3] => element_10 
        [4] => element_12 
        [5] => element_14 
        [6] => element_4 
        [7] => element_2 
        [8] => element_3 
        [9] => element_9 
        [10] => element_13 
        [11] => element_7 
          ) 
) 

Where I want the array in this format:

Array ( 
  [0] => Array ( 
         [0] => element_10 
         [1] => block_1 
         [2] => element_4 
         [3] => element_1 
         [4] => element_3 
               ) 
[1] => Array ( 
        [1] => block_2 
        [2] => element_8 
        [4] => element_12 
        [5] => element_14 
        [7] => element_2 
        [9] => element_9 
        [10] => element_13 
        [11] => element_7 
          ) 
) 

Ican setup the key indexes later.

I tried:

function multi_unique($array) {
    foreach ($array as $k=>$na)
        $new[$k] = serialize($na);
    $uniq = array_unique($new);
    foreach($uniq as $k=>$ser)
        $new1[$k] = unserialize($ser);
    return ($new1);
}

No Luck, then I tried:

function array_unique_multidimensional($input)
{
    $serialized = array_map('serialize', $input);
    $unique = array_unique($serialized);
    return array_intersect_key($input, $unique);
}

Still same array returning.

I tried this method too:

function super_unique($array)
{
  $result = array_map("unserialize", array_unique(array_map("serialize", $array)));

  foreach ($result as $key => $value)
  {
    if ( is_array($value) )
    {
      $result[$key] = self::super_unique($value);
    }
  }
  return $result;
}

Please help me, I know it's pretty simple I don't know where I'm losing?

Thanks,

3 Answers 3

2

You need to iterate over your list of input arrays. For each value in that array, you need to see if you've previously encountered it, so you'll have to keep a super-set of all values across all arrays, which you gradually append to. If a value already exists in the super-set array, you can remove it, otherwise you can append it.

function multi_unique($arrays) {
  $all_values = array();

  foreach ($arrays as &$array) {
    foreach ($array as $index => $value) {
      if (in_array($value, $all_values)) {
        // We've seen this value previously
        unset($array[$index]);
      } else {
        // First time we've seen this value, let it pass but record it
        $all_values[] = $value;
      }
    }
  }
  return $arrays;
}


$values = array (
  array ( 'element_10', 'block_1', 'element_4', 'element_1', 'element_3',) ,
  array ( 'block_1', 'block_2', 'element_8', 'element_10', 'element_12', 'element_14', 'element_4', 'element_2', 'element_3', 'element_9', 'element_13', 'element_7',)
);

var_dump(multi_unique($values));

Output:

array(2) {
  [0]=>
  array(5) {
    [0]=>
    string(10) "element_10"
    [1]=>
    string(7) "block_1"
    [2]=>
    string(9) "element_4"
    [3]=>
    string(9) "element_1"
    [4]=>
    string(9) "element_3"
  }
  [1]=>
  array(8) {
    [1]=>
    string(7) "block_2"
    [2]=>
    string(9) "element_8"
    [4]=>
    string(10) "element_12"
    [5]=>
    string(10) "element_14"
    [7]=>
    string(9) "element_2"
    [9]=>
    string(9) "element_9"
    [10]=>
    string(10) "element_13"
    [11]=>
    string(9) "element_7"
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

there's a typo for $index, $value to $index => $value but the thing is I don't want to merge arrays I want to keep the [0] = [0] => element_10 [1] => block_1 [2] => element_8 .... [1] = [0] => element_1 [1] => block_2 [2] => element_10 ....
Perfect you're life savior @meagar :)
Think performace! Look at @moonwave99 answer below.
@user3165879 Think "learning to program". My answer was meant to educate on why the posted attempts were wrong, not to be the most performant solution. I took it for granted that the goal was to operate on a list of two or more arrays; if the goal really is to just diff two arrays, then yes, array_diff is the way to go.
1

If you just want to remove duplicates from the second entry of your array, use array_diff():

$array[1] = array_diff($array[1], $array[0]);

Iterate if you want to apply it to an arbitrary length.

1 Comment

Best solution!! Better that looping over array so much nested loops. But it only needs to be adapted to more than 2 elements array. +1 anyway
0

Why are you using the serialize function.

Use array_diff instead.

A simple would be.

$orginal = array(array(values), array(values), ...);

$copy = $original;

foreach($original as $k => $subArray) {
    $tmpCopy = $copy;
    unset($tmpCopy[$k]);
    unshift($tmpCopy, $subArray);
    $tmpCopy = array_values($tmpCopy);
    $original[$k] = call_user_func_array('array_diff', $tmpCopy);
}

This works for a two dimensions array.

Hope it helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.