2

I need your help. I've done various research and no testing method worked with 3 levels or more arrays. I need to leave only the only ones values in the multidimensional array ..

See this example

My Array:

Array
(
    [sucesso] => Array
        (
            [LAUDO_VISTORIA] => Array
                (
                    [0] => 0027
                    [2] => 30027
                    [3] => 0027
                )
            [LAUDO] => Array
                (
                    [0] => 0027
                    [2] => 30027
                    [3] => 0027
                )
            [DADOS_DO_VEICULO] => Array
                (
                    [0] => 0027
                    [1] => 30027
                )
        )
    [code] => 201
)

1 Answers1

2

Please note that if you have numbers with leading zero, you should store them to as strings, otherwise they will be interpreted as octal numbers. You can use (int) to get the correct type cast, when you output them.

The first code below flatten the array by the use of serialize as callback in array_map, duplicates are removed using array_unique, then put back together using array_intersect_key, the process is looped to get to deeper levels of the array.

The second code below, follows the same logic but array_unique is only performed at the deepest level of each array key path. An if/else statement has been added, as not all array key path are of the same length/depth. (If anyone knows of a better way to do so, please let me know.)

serialize can be replaced with json_encode, but I am not sure which is faster.

I am not very good at explaining how things work, please feel free to edit, if you can rephrase what I've said above better.

To remove duplicates in multidimensional arrays, both duplicated sub-arrays and elements.

    function multi_unique($array){
        $temp = array_intersect_key($array, array_unique(array_map("serialize", $array)));
        foreach ($temp as $key => $value){
            if ( is_array($value) ){
                $temp[$key] = multi_unique($value);
            }
        }
        return $temp;
    }

To remove duplicate elements from the sub-array of the deepest end of each key path.

    function multi_unique($array){
        $temp = array_intersect_key($array, array_map("serialize", $array));
        foreach ($temp as $key => $value){
            if (is_array($value)){
               $temp[$key] = multi_unique($value);
            }
//the else if statement is to counter the problem where the deepest level of each path is different
            else if (count($temp) == count($temp, COUNT_RECURSIVE)){
                $temp=array_unique($temp);
            }
        }
        return $temp;
    }
SML
  • 1,235
  • 6
  • 17
  • It will not always be number can be string – Níssius Guilet Ribas Jun 14 '16 at 14:56
  • My code works for both numbers and strings. What I was saying is, if you want to store numbers such as '0123', '0104', you need to store them as strings not number, hence the apostrophe/quotation marks, otherwise they will be treated as octal numbers, 0123(octal) will be translated as 84 (dec). – SML Jun 14 '16 at 15:00
  • If you use a leading zero, the number is interpreted by PHP as an octal number. You can google it – SML Jun 14 '16 at 15:03
  • Did not working. it looked like this: http://i.stack.imgur.com/Nt5CG.png – Níssius Guilet Ribas Jun 15 '16 at 20:17
  • Array ( [sucesso] => Array ( [LAUDO_VISTORIA] => Array ( [0] => 0027 [2] => 30027 [3] => 0027 ) [LAUDO] => Array ( [0] => 0027 [2] => 30027 [3] => 0027 ) [DADOS_DO_VEICULO] => Array ( [0] => 0027 [1] => 30027 ) ) [code] => 201 ) – Níssius Guilet Ribas Jun 15 '16 at 20:26
  • @NíssiusGuiletRibas Let me know if the second code works for you, added explanation of how it works and why you the first code didn't work for you. – SML Jun 16 '16 at 17:13