0

I have a multidimensional Array I want to delete all duplicate keys, I've tried but not working any script.

Following answer is working for duplicate values and I want same solution for duplicate keys in multidimensional array.

PHP remove duplicate values from multidimensional array

$arr = array(
    "a" => "xxx",
    "b" => "xxx",
    "c" => array(
        "g" => "xxx",
        "a" => "xxx",
        "h" => "xxx",
    ),
    "d" => "xxx",
    "e" => array(
        "i" => array(
            "a" => "xxx",
            "k" => array(
                "l" => "xxx",
                "b" => "xxx",
            ),
        ),
        "j" => "xxx",
    ),
    "f" => "xxx",
);

I want this result:

$arr = array(
    "a" => "xxx",
    "b" => "xxx",
    "c" => array(
        "g" => "xxx",
        "h" => "xxx",
    ),
    "d" => "xxx",
    "e" => array(
        "i" => array(
            "k" => array(
                "l" => "xxx",
            ),
        ),
        "j" => "xxx",
    ),
    "f" => "xxx",
);

I'm trying to solve this issue by this function:

function array_unique_key($array) { 
    $result = array(); 
    foreach (array_unique(array_keys($array)) as $tvalue) {
        if (is_array($tvalue)) {
            $result[$tvalue] = $array[$tvalue]; 
        }
        $result[$tvalue] = $array[$tvalue]; 
    } 
    return $result; 
} 
Shahrukh
  • 47
  • 2
  • 10
  • Make an array containing the keys you've copied to the result. Then process the array recursively. Check each key to see if it's in the array. If it is, return from the function. If not, add it to the array and process the element. If it's a nested array, create an empty array in the key, and recurse; if it's a scalar, just assign the value to the key in the result. – Barmar Feb 11 '19 at 23:12

2 Answers2

2

This function will do what you want. It recursively traverses the array, looking for keys which have already been encountered and where it finds them, unsetting that element from the array. Note we pass $array and $keys by reference to the function so they can be changed (thanks @Don'tPanic for pointing out the need for $keys being by reference as well):

function remove_dup_keys(&$array, &$keys = array()) {
    foreach ($array as $key => &$value) {
        if (in_array($key, $keys)) {
            unset($array[$key]);
        }
        else {
            $keys[] = $key;
        }
    }
    foreach ($array as $key => &$value) {
        if (is_array($value)) {
            remove_dup_keys($value, $keys);
        }
    }
}

Output:

Array (
    [a] => xxx
    [b] => xxx
    [c] => Array (
        [g] => xxx
        [h] => xxx
    )
    [d] => xxx
    [e] => Array (
        [i] => Array (
             [k] => Array (
                 [l] => xxx
             )
        )
        [j] => xxx
    )
    [f] => xxx 
)

Demo on 3v4l.org

Nick
  • 138,499
  • 22
  • 57
  • 95
  • I found an error, its working only for first keys like [a] [b] [c] [d] [e] [f], if i repeat [h] it is not working :( – Shahrukh Feb 12 '19 at 06:45
  • @ShahrukhRaza can you give me some sample data? – Nick Feb 12 '19 at 06:47
  • @ShahrukhRaza I'd still like to see your sample data so that I can fix this code for anyone else that sees the question. – Nick Feb 12 '19 at 06:49
  • @ShahrukhRaza I've made a change to my code based on what I think the problem is likely to be. Can you let me know if it resolves the problem you found? – Nick Feb 12 '19 at 07:00
2

Another option if you want to keep the original array.

function array_unique_key($input, &$keys = []) {

    // filter any preexisting keys from the input while adding its keys to the set of unique keys

    $input = array_filter($input, function($key) use (&$keys) {
        return isset($keys[$key]) ? false: $keys[$key] = true;
    }, ARRAY_FILTER_USE_KEY);

    // recursively map this function over the remaining values

    return array_map(function($value) use (&$keys) {
        return is_array($value) ? array_unique_key($value, $keys): $value;
    }, $input);

}
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
  • I always seem to struggle to get my head around using `array_map` to recurse. This is a good example. I added it to my demo https://3v4l.org/ZcGfW – Nick Feb 12 '19 at 00:57
  • @Nick thanks! I know what you mean. I find it easier to visualize recursion if I sort of forget about the recursion and just consider the result of the recursive call as a value that could be produced by any function. Haha I don't know if that even makes sense, but it's the best way I can think of to describe it – Don't Panic Feb 12 '19 at 01:08