0

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.

George Kagan
  • 5,913
  • 8
  • 46
  • 50
Aagrlp640
  • 70
  • 1
  • 7
  • check here: http://stackoverflow.com/questions/21832701/does-json-syntax-allow-duplicate-keys-in-an-object – Dekel Nov 08 '16 at 18:50

3 Answers3

2

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

FirePanther
  • 355
  • 1
  • 8
1

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
)
Dion
  • 3,145
  • 20
  • 37
  • Hi Dion, thanks for your answer, actually it works great, but the items are generated ramdomly "list_..." – Aagrlp640 Nov 08 '16 at 19:48
  • could it be possible to fix the duplicate entries at the origin where the json comes from? The problem is that json actually doesn't support duplicate keys either so basically your json strings are not valid... – Dion Nov 08 '16 at 19:52
  • I have it like this before that $tree = 'list[Gentlemen]=null&list[Gold]=Gentlemen&list[Ladies]=null&list[Plata]=Ladies&list[Gold]=Ladies'; – Aagrlp640 Nov 08 '16 at 20:00
  • You mean you had multiple arrays for each key in the format `list[key]=value`? Does this data come from a GET or POST request or what format is the string? If you have all these Arrays in one array (or $_GET or something like that) you could parse them much better as you don't have the duplicate keys, iterate through the arrays and merge it together to one array where you rename duplicate keys. – Dion Nov 08 '16 at 20:05
  • Below theres what i have – Aagrlp640 Nov 08 '16 at 20:09
0

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);
Dion
  • 3,145
  • 20
  • 37
Aagrlp640
  • 70
  • 1
  • 7
  • Can you add the code of how you converted it to json? And what exact data do you need from the string? Because in the last example (with `[Gentleman] [Gold] ... `) you don't have the values anymore. – Dion Nov 08 '16 at 20:11
  • $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); – Aagrlp640 Nov 08 '16 at 20:13
  • I updated your post above and added the code there for better readability, but I now got what you want to achieve. You only need the values inside the brackets right? And btw. you should edit your actual question post rather than adding an answer to your own question with more details ;) – Dion Nov 08 '16 at 20:15
  • Ok, thanks, actually change the repeat values inside brackets [] – Aagrlp640 Nov 08 '16 at 20:18
  • From the $tree above you want to have the following values at the end: `Gentleman, Gold, Ladies, Silver, Gold_2/Gold2`? – Dion Nov 08 '16 at 20:20
  • I mean like this list[Gentlemen]=null&list[Gold]=Gentlemen&list[Ladies]=null‌​&list[Plata]=Ladies&‌​list[Gold2]=Ladies' – Aagrlp640 Nov 08 '16 at 20:22
  • But the values inside are dinamically change, and also the amount of elements – Aagrlp640 Nov 08 '16 at 20:23