Can I Rely on the Order of a JSON Array? [duplicate] - javascript

This question already has answers here:
Is the order of elements in a JSON list preserved?
(5 answers)
Closed 6 years ago.
It's obvious that I can't rely on the ordering of key-value pairs in JSON. For example, a JSON parser could interpret
{
"someKey" : "someValue",
"anotherKey" : "anotherValue",
"evenAnotherKey" : "evenAnotherValue"
}
as
{
"anotherKey" : "anotherValue",
"someKey" : "someValue",
"evenAnotherKey" : "evenAnotherValue"
}
legally, but could I rely on the ordering of a JSON array? For example, could a JSON parser interpret
{
"arrayKey" : ["firstElement", "secondElement", "thirdElement"]
}
as
{
"arrayKey" : ["secondElement", "firstElement1", "thirdElement"]
}
legally? I'd assume not, but my friend told me that I was incorrect.

Yes, you can! Arrays are made, so that order matters! That is what divides Objects from Arrays. Especially in JS and JSON.

Arrays and lists are always ordered. That's the point of having arrays and lists - their position is their index.
Incidentally, since ES5 the order of objects (what you call key-value pairs) are guaranteed as well. But not in a straightforward way.
For objects, any key that is a number will be ordered before non-numeric keys and will be ordered numerically. But all other keys are guaranteed to be in insertion order. So the following object:
{
hello : "world",
foo : "bar",
"22" : "first"
}
must be returned as:
{
"22" : "first",
hello : "world",
foo : "bar"
}
Currently all browsers support this and node.js support this but not all javascript cross-complier (like Babel) support it.
Personally I don't like to treat unordered data structures like objects as ordered. But it looks like the js community disagrees. Go for example deliberately randomises the ordering of maps to prevent people from relying on any accidental stable ordering from an implementation of the language.

Related

javascript- How to parse JSON using javascript [duplicate]

This question already has answers here:
How can I access and process nested objects, arrays, or JSON?
(31 answers)
Closed 5 years ago.
If my json is this:
[
["cat1"],
["cat2"],
["cat3"],
["cat4"],
["cat5"]
]
How to parse this in javascript. I am looking for some for loop kind of solution which can iterate over the json and can give me "cat1 ", "cat2" etc.
P.S.: My json list is dynamic which i am getting from some source. So, i dont know how my json elements are there and what are the fields.
Most browsers support JSON.parse(), which is defined in ECMA-262 5th Edition (the specification that JS is based on). Its usage is simple:
var json = '{"result":true,"count":1}',
obj = JSON.parse(json);
alert(obj.count);
For the browsers that don't you can implement it using json2.js.
As noted in the comments, if you're already using jQuery, there is a $.parseJSON function that maps to JSON.parse if available or a form of eval in older browsers. However, this performs additional, unnecessary checks that are also performed by JSON.parse, so for the best all round performance I'd recommend using it like so:
var json = '{"result":true,"count":1}',
obj = JSON && JSON.parse(json) || $.parseJSON(json);
This will ensure you use native JSON.parse immediately, rather than having jQuery perform sanity checks on the string before passing it to the native parsing function.
try this.
var list= [
["cat1"],
["cat2"],
["cat3"],
["cat4"],
["cat5"]
];
list.forEach(function(item){
console.log(item[0]);
});

How to create a JSON object with duplicate keys [duplicate]

This question already has answers here:
Sailsjs Mysql ORM multiple query on the same table field
(2 answers)
Closed 7 years ago.
I'm working on a SailsJS project and I need to create a json object for my ORM search to work, This is how the search should be performed
Venue.find({
is_published: true,
restaurant_services: {
contains: '"delivery":"1"',
contains: '"takeout":"1"'
},
restaurant_specialties: {
contains: '"breakfast":"1"',
}
}).exec
So as you may see the JSON object inside the Find() is the one O need to create and the values inside has duplicate keys.
You can't. Your should try using something like this instead:
Venue.find({
is_published: true,
restaurant_services: {
contains: ['"delivery":"1"','"takeout":"1"']
},
restaurant_specialties: {
contains: [ '"breakfast":"1"' ]
}
}).exec
Or this:
Venue.find({
is_published: true,
restaurant_services: {
contains: {"delivery":"1","takeout":"1"}
},
restaurant_specialties: {
contains: { "breakfast":"1" }
}
}).exec
The problem is that the {... } Jason represents a map and therefore can't have duplicate keys. Although duplicate keys are strictly not Syntax errors but they are going to able also not going to work as expected with browsers or json libraries. If you can't change the syntax for your json object then you will have to produce that json by string concatenation instead of the normal Javascript type approach.

How are objects in JavaScript stored in memory?

On the official documentation of JSON
An object is an unordered set of name/value pairs. An object begins
with { (left brace) and ends with } (right brace). Each name is
followed by : (colon) and the name/value pairs are separated by ,
(comma).
Note
I am Javascript newbie, and from the name JSON (Javascript object notation) itself, I am assuming objects in Javascript are same as JSON. Please correct me in case I have got it wrong.
From the above definition it seems the Javascript objects are most probably implemented by either a hashmap or a BST or some similar data-structure.
But when I insert key value pairs in Node shell, they are inserted in serialised manner. This is what I tried in node shell
> var a = {}
undefined
> a['k1'] = 'a1'
'a1'
> a['k3'] = 'a3'
'a3'
> a['k2'] = 'a2'
'a2'
> a['k4'] = 'a4'
'a4'
> a['k5'] = 'a5'
'a5'
> a
{ k1: 'a1',
k3: 'a3',
k2: 'a2',
k4: 'a4',
k5: 'a5' }
Now, on printing a the key value pairs are returned in the same order as that of insertion. So my questions are:
Do I get fast lookups for a key? I mean complexity of O(log(n)) or better.
In case JSON is not using a data-structure like a BST, hashmap or some similar DS, then how exactly are JSON objects layed under the memory?
Update
Ok, so what about Javascript objects. Can someone comment on the underlying implementation of Javascript objects.
You're confusing JSON, which is only a text-based serialization format enabling simple data exchange, and plain javascript objects, which are unordered lists of properties.
As said by the MDN :
An object is a collection of properties, and a property is association
between a name and a value. A value of property can be a function,
which is then known as the object's method.
Objects properties can be seen as hash maps, as they're not ordered. But it's often a little more complicated : when objects are prototype based, properties not found on an object are searched upward the prototypes it's based on.
With javascript objects you get a guaranteed fast look-up, as this is an essential part of the implementation. But the implementation isn't defined by the norm and each engine can have its own.
Update
Starting from ES6, which you have in almost all browsers and JS servers in 2021, the order of non integer keys in object is the insertion order.

Is the order of elements in a JSON list preserved?

I've noticed the order of elements in a JSON object not being the original order.
What about the elements of JSON lists? Is their order maintained?
Yes, the order of elements in JSON arrays is preserved. From RFC 7159 -The JavaScript Object Notation (JSON) Data Interchange Format
(emphasis mine):
An object is an unordered collection of zero or more name/value
pairs, where a name is a string and a value is a string, number,
boolean, null, object, or array.
An array is an ordered sequence of zero or more values.
The terms "object" and "array" come from the conventions of
JavaScript.
Some implementations do also preserve the order of JSON objects as well, but this is not guaranteed.
The order of elements in an array ([]) is maintained. The order of elements (name:value pairs) in an "object" ({}) is not, and it's usual for them to be "jumbled", if not by the JSON formatter/parser itself then by the language-specific objects (Dictionary, NSDictionary, Hashtable, etc) that are used as an internal representation.
Practically speaking, if the keys were of type NaN, the browser will not change the order.
The following script will output "One", "Two", "Three":
var foo={"3":"Three", "1":"One", "2":"Two"};
for(bar in foo) {
alert(foo[bar]);
}
Whereas the following script will output "Three", "One", "Two":
var foo={"#3":"Three", "#1":"One", "#2":"Two"};
for(bar in foo) {
alert(foo[bar]);
}
Some JavaScript engines keep keys in insertion order. V8, for instance, keeps all keys in insertion order except for keys that can be parsed as unsigned 32-bit integers.
This means that if you run either of the following:
var animals = {};
animals['dog'] = true;
animals['bear'] = true;
animals['monkey'] = true;
for (var animal in animals) {
if (animals.hasOwnProperty(animal)) {
$('<li>').text(animal).appendTo('#animals');
}
}
var animals = JSON.parse('{ "dog": true, "bear": true, "monkey": true }');
for (var animal in animals) {
$('<li>').text(animal).appendTo('#animals');
}
You'll consistently get dog, bear, and monkey in that order, on Chrome, which uses V8. Node.js also uses V8. This will hold true even if you have thousands of items. YMMV with other JavaScript engines.
Demo here and here.
"Is the order of elements in a JSON list maintained?" is not a good question. You need to ask "Is the order of elements in a JSON list maintained when doing [...] ?"
As Felix King pointed out, JSON is a textual data format. It doesn't mutate without a reason. Do not confuse a JSON string with a (JavaScript) object.
You're probably talking about operations like JSON.stringify(JSON.parse(...)). Now the answer is: It depends on the implementation. 99%* of JSON parsers do not maintain the order of objects, and do maintain the order of arrays, but you might as well use JSON to store something like
{
"son": "David",
"daughter": "Julia",
"son": "Tom",
"daughter": "Clara"
}
and use a parser that maintains order of objects.
*probably even more :)

Chrome sorts objects by key [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Chrome and probably Opera sort object properties automatically
I have a very simple code:
var obj = {3:'a',2:'b',1:'c'};
console.log(obj);
In Firefox 4.0.1 it returns:
Object { 3="a", 2="b", 1="c"}
In Chrome 11.0.696.71 it returns:
Object { 1="c", 2="b", 3="a"}
How can I coerce Chrome doesn't sort this object?
For Objects the spec is that the order of elements is not preserved. In other words javascript doesn't guarantee any particular order for the properties of an Object.
You'll have to use an array if you want to preserve the order of elements. In this case, your Object can be rewritten to:
var arrobj = ['c','b','a'];
or
var arrobj = ['a','b','c'].reverse();
Where you have take into account that the first element index will be 0 (zero)
It's a known "bug"/feature of chrome. Even author of jQuery indignant of this, but chrome guys stay inflexible, saying that this is a "feature":
http://code.google.com/p/chromium/issues/detail?id=883 [1]
As a workaround use arrays or some kind of MixedCollection (as in extjs) or something similar.
null !== true and also null !== false // in php and js it's so
[1]: John Resig (jeresig) is an author of jquery

Categories

Resources