0

Initial PHP ARRAY Storing attributes as values and respective id's on key

Array
(
[979] => Pict Model
[962] => Brand
[494] => Dimensions
[980] => Capacity
[981] => Power
[982] => List Price
[983] => Warrenty
[975] => USB Connection
[976] => Self Cleaning
[977] => Double Glass Door
[978] => Steam Function
[974] => Electricity Type
)

In my Code below, comparable_attr holds the json encoded array. After that, as i console.log(comparable_attr) This gives me a json of order as of php array.

Then, after i parseJSON and then console.log it gave me data in different order.

var comparable_attr = '<?php echo json_encode($_comparable_attributes); ?>';
   if(comparable_attr.length != 0){       //check for empty json
      console.log(comparable_attr);
          var obj = jQuery.parseJSON(comparable_attr);
                console.log(obj);
}

Problem : i want to achieve it in same order after i parseJSON.

The result obtained :

First Console.log(comparable_attr) gives:

{"979":"Pict Model","962":"Brand","494":"Dimensions","980":"Capacity","981":"Power","982":"List Price","983":"Warrenty","975":"USB Connection","976":"Self Cleaning","977":"Double Glass Door","978":"Steam Function","974":"Electricity Type"}

Second Console.log(obj) gives :

 Object { 494="Dimensions", 962="Brand", 974="Electricity Type", more...}

enter image description here

Edited :

What i have found is, it shorted according to my attribute id, which i need in the same order as it is in array.

Suman KC
  • 3,478
  • 4
  • 30
  • 42
  • 1
    Take a look at this question, it may help you out: http://stackoverflow.com/questions/12574068/jquery-getjson-sorts-my-data-by-id-automatically – Matheno Oct 10 '14 at 07:41
  • yeah quite odd indeed, maybe related http://stackoverflow.com/questions/21216391/prevent-json-encode-associative-array-sorting – Kevin Oct 10 '14 at 07:48
  • 1
    @Ghost it's not odd at all, it's a natural consequence of JS objects being explicitly _unordered_. – Alnitak Oct 10 '14 at 08:04
  • @Alnitak yeah thanks for shedding light on this – Kevin Oct 10 '14 at 08:13

2 Answers2

3

When you convert a PHP spare array into JSON and subsequently into a JS variable you will get a JS Object, not an array, and JS objects are explicitly an unordered set of key value pairs.

If you wish to preserve the order you will need to rearrange the data on the PHP side first, perhaps as:

Array(
    Array([979] => Pict Model),
    Array([962] => Brand),
    ...
)

Note however that if you do this you will lose the ability to directly lookup the data by key, as the resulting JS object would look like:

[
  { "979": "Pict Model" },  // NB: all JS keys are strings
  { "962": "Brand" },
  ...
]

An alternative might be to send your existing array as is, but also send a second array that is just the ordered list of keys. The former can be used for key-based lookup, the latter to determine the correct order:

json_encode(array(
    'data' => $_comparable_attributes,
    'order' => array_keys($_comparable_attributes)
));
Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • what about swapping key and values form my array as both are string to me ? i solved that way (as it didn't sorted the alphabet being on key) but is it right to do this way ? – Suman KC Oct 10 '14 at 08:25
  • @K.C. hard to say without knowing why the order matters. Swapping the keys and values will still give you an object that's not sorted. – Alnitak Oct 10 '14 at 08:29
  • But Swapping gave me the same order as of php Array. Yeah, actually ordering matters here, it's that kinda case. Anyways Thank you. – Suman KC Oct 10 '14 at 08:33
  • @K.C. you can't rely on that ordering being preserved - in other browsers it could well be different. – Alnitak Oct 10 '14 at 08:52
0

Javascript’s json object order is inplementation dependant. You could try it in the console:

a = {2:'a', 1:'b'}
Object {1: "b", 2: "a"}

To solve your problem I would suggest you to prevent auto sorting by:

array_reduce(
  $a, 
  function($carry, $item) use(&$a) { 
    $carry[] = [key($a), $item]; next($a); return $carry; 
  }, 
  []
)

This will wrap your initial array into array containing [key, val] items.

Hope this helps.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160