2

First this is not a duplicate questions. I've looked through some similar problem and most of the answer is what I am using right now.

Here is the problem set up, on PHP side

$array = array('name' => 'a', 'data' => array('0'=>15,'0.25'=>'18','0.35'=>19,'1' =>20));
echo json_encode($array);

on the JS side

data = $.parseJSON(data); // data is the return from the php script above

As you can see the $array['data'] is an associative array with numeric number as its key and sorted in order. While parsing into JSON, javascript altered the order of that array and sorted 0 and 1 as numeric key and put them to the head of the object.

I know this is standard behavior for certain browser such as chrome, and IE9. I've read somewhere that people suggest stick with array strictly if I want to maintain the order of the array. But my question is how do you feed back an array from PHP to javascript as an array instead of using json object? Or is there other solution to this kind of problem . Thanks for the input in advance.

Thanks for the input in advance

Gäng Tian
  • 1,588
  • 2
  • 18
  • 26
  • Afaik, JSON parsers don't guarantee any order when decoding, you'd need to use another field (or array) to preserve your order, using keys won't work. – aknosis Jun 05 '12 at 23:38

3 Answers3

3

Use an array to maintain order, and then an object to create the map. There are two ways. I would suggest:

$array = array('name' => 'a', 'data' => 
  array(
    array('key' => 0, 'value' => 15),
    array('key' => 0.25, 'value' => 18),
    array('key' => 0.35, 'value' => 19),
    array('key' => 1, 'value' => 20),
  )
);
echo json_encode($array);

Which will give you the JSON:

{
    "name": "a",
    "data": [
       {"key": 0, "value": 15},
       {"key": 0.25, "value": 18},
       {"key": 0.35, "value": 19},
       {"key": 1, "value": 20}
    ]
}

Then you will have order but to look up a certain key will be more difficult. If you want that to be easy you can return a mapping object as well like this:

$array = array('name' => 'a', 'data' => 
  array(
    "0" => 15,
    "0.25" => 18,
    "0.35" => 19,
    "1" => 20,
  ),
  'order' => array("0", "0.25", "0.35", "1")
);
echo json_encode($array);

Which will give you:

{
    "name": "a",
    "data": {
       "0": 15,
       "0.25": 18,
       "0.35": 19,
       "1": 20
    },
    "order": ["0", "0.25", "0.35", "1"]
}

One of these two methods of returning your data should prove to be the most useful for your specific use case.

Paul
  • 139,544
  • 27
  • 275
  • 264
  • Thanks for the suggestion, that sure will do the trick. I end up fetching out $array['data'] in javascript to an array there and did a sort on it. I will try your suggestion and see which on will blend in more nature to the code I am using now. the whole JSON object is a object for plotting graph on web front by JS, so I will have to make it as transparent as to the function that's calling the object to plot :x but you sure gave me some good idea to start there. Thanks! – Gäng Tian Jun 05 '12 at 23:56
0

Actually, it's PHP that takes the "0" and "1" keys and makes them numeric keys. This has nothing to do with your JavaScript.

There isn't any real way to work around this, but ideally your code should not rely on such things as "what order the keys of an object are in". It may be a better idea, just from what I see here, to separate the data into an array of keys and an array of values, then zip them back together on the JS side.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
0

I'd suggest another field for storing order.

$array = array('name' => 'a',
               'data' => array('0'=>15,'0.25'=>'18','0.35'=>19,'1' =>20),
               'order'=> '0,0.25,0.35,1'
          );
echo json_encode($array);
aknosis
  • 3,602
  • 20
  • 33