Aagrlp640
Aagrlp640

Reputation: 70

PHP - Rename repeat keys in JSON array

More info: I forgot to mention that items like list_... are generated randomly

I have a text that I convert it to array using json

$tree = '{"list_Gentlemen":"root","list_Gold":"list_Gentlemen","list_Ladies":"root","list_Plata":"list_Ladies","list_Gold":"list_Ladies"}';

I convert it with

$tree = json_decode($tree,true);

But the thing is that when I convert it to array echo $tree; returns me

Array
(
    [list_Gentlemen] => root
    [list_Gold] => list_Ladies
    [list_Ladies] => root
    [list_Plata] => list_Ladies
)

I mean there's a repeat key [list_Gold], and it doesn't insert the repeated key. Is there a way to rename that key?

Array
(
    [list_Gentlemen] => root
    [list_Gold] => list_Gentlemen
    [list_Ladies] => root
    [list_Plata] => list_Ladies
    [list_Gold] => list_Ladies
)

Thanks for your help.

Upvotes: 0

Views: 754

Answers (3)

FirePanther
FirePanther

Reputation: 355

You could add the index of the array item, thusly there can't be any doubles:

<?php
$tree = '{"list_Gentlemen":"root","list_Gold":"list_Gentlemen","list_Ladies":"root","list_Plata":"list_Ladies","list_Gold":"list_Ladies"}';

preg_match_all('~(,|\{)\s*"([^"]*)"\s*:~', $tree, $matches, PREG_SET_ORDER);
foreach ($matches as $i => $m) {
    $tree = implode($m[1].'"'.$i.'-'.$m[2].'":', explode($m[0], $tree, 2));
}

print_r(json_decode($tree, 1));

result:

Array
(
    [0-list_Gentlemen] => root
    [1-list_Gold] => list_Gentlemen
    [2-list_Ladies] => root
    [3-list_Plata] => list_Ladies
    [4-list_Gold] => list_Ladies
)

or create a multi dimensional array:

<?php
$tree = '{"list_Gentlemen":"root","list_Gold":"list_Gentlemen","list_Ladies":"root","list_Plata":"list_Ladies","list_Gold":"list_Ladies"}';

$tree = preg_replace('~(,|\{)(\s*"[^"]*"\s*:\s*"[^"]*")~', '$1{$2}', trim($tree));
$tree = '['.substr($tree, 1, strlen($tree) - 2).']';

print_r(json_decode($tree, 1));

result:

Array
(
    [0] => Array
        (
            [list_Gentlemen] => root
        )

    [1] => Array
        (
            [list_Gold] => list_Gentlemen
        )

    [2] => Array
        (
            [list_Ladies] => root
        )

    [3] => Array
        (
            [list_Plata] => list_Ladies
        )

    [4] => Array
        (
            [list_Gold] => list_Ladies
        )

)

edit: if you have control over the style of your json you could just generate it this way: [{"key":"value"},{"key","value"}], this way you can skip the regex part of my second solution

Upvotes: 2

Dion
Dion

Reputation: 3345

Update: You could replace the duplicate keys with some regex, but this only works if there are max 2 duplicates each key: $tree = preg_replace('/\[(\w{2,})(?=.*?\\1)\]\W*/', '[$1_2]=', $tree); this would have the following output: list[Gentlemen_2]=null&list[Gold_2]=Gentlemen&list[Ladies_2]=null&list[Plata]=Ladies&list[Gold]=Ladies

Having an Array with a duplicate key (list_Gold) is not possible, as duplicate's in PHP Arrays aren't supported. What you could do, is to parse the JSON string before decoding, and rename duplicates (if it's only this one index you could always replace the second match of list_Gold with list_Gold_2 for example).

This could look like this:

$tree1 = substr($tree, 0 , strpos($tree, 'list_Gold') + 2);
$tree2 = substr($tree, strpos($tree,'list_Gold') + 2);
$tree2 = str_replace('list_Gold', 'list_Gold_2', $tree2);
$tree = $tree1 . $tree2;
$treeArray = json_decode($tree, true);

Contents of the array above:

Array
(
    [list_Gentlemen] => root
    [list_Gold] => list_Gentlemen
    [list_Ladies] => root
    [list_Plata] => list_Ladies
    [list_Gold_2] => list_Ladies
)

Upvotes: 1

Aagrlp640
Aagrlp640

Reputation: 70

Thanks Dion, The only thing is that i only have acces to:

$tree = 'list[Gentlemen]=null&list[Gold]=Gentlemen&list[Ladies]=null&list[Silver]=Ladies&list[Gold]=Ladies'; 

I did the conversion to json array format, I was thinking in just leaving using str_replace like this

$text = '[Gentlemen] [Gold] [Ladies] [Silver] [Gold]';

But I dont know how to remove the text arround brackets, and after then it would be easy to modify them using explode or something like that

Code of conversion to JSON:

$tree = 'list[Gentlemen]=null&list[Gold]=Gentlemen&list[Ladies]=null‌​&list[Plata]=Ladies&‌​list[Gold]=Ladies';
$tree = str_replace('=null','":"root',$tree);
$tree = str_replace('=','":"list_',$tree);
$tree = str_replace('[','_',$tree);
$tree = str_replace(']','',$tree);
$tree = str_replace('&','","',$tree);
$tree = '{"'.$tree.'"}';
$tree = str_replace('=null','":"root',$tree); $tree = json_decode($tree,true);

Upvotes: 0

Related Questions