0

I'm not sure my searching skills are strong enough to find a solution on my own, since I did try, but with no luck unfortunately to such a rudimentary question. Apologies in advance.

Basically, I have a JSON object which has multiple keys with the same name, eg:

{"type": "Item", "type": "Item2", "name": "Item Name", "name": "Item Name2"}

Now if I do $.each, it loops through all of them resulting in two type keys and two name keys, but I'd like to only show the first one with such a key and not the rest. In other words, I want to only show unique keys in the form of first looped, first shown.

6
  • 3
    That's not valid JSON... Commented Feb 16, 2015 at 13:19
  • 2
    An object can't have multiple properties with same name. Please show full code that you use for loop. Fix source if you are sending this as JSON Commented Feb 16, 2015 at 13:19
  • 1
    My guess is you don't have a JSON object. A "JSON object" is text defining an object using JSON notation, like this string: '{"foo":"bar"}' or the equivalent (without outer quotes) in a file or as an XHR response body. If you don't have text, it's not JSON anymore, it's just a JavaScript object. Commented Feb 16, 2015 at 13:20
  • $.each({"type": "Item", "type": "Item2", "name": "Item Name", "name": "Item Name2"}, function(key, value) {console.log(key);});: "type", "name". Commented Feb 16, 2015 at 13:21
  • Apparently my $.ajax call loads the thing twice, so hence I'd like to filter it. Commented Feb 16, 2015 at 13:24

2 Answers 2

1

First off, my guess is you don't really have JSON, just an object. But it doesn't really matter either way.

A JavaScript object (and an object described in JSON notation) can have only one property with a given name. If you have what you describe in JavaScript source code:

var data = {"type": "Item", "type": "Item2", "name": "Item Name", "name": "Item Name2"};

...in loose mode you end up with an object with only two properties: type and name, with the values "Item2" and "Item Name2" respectively (the properties are assigned in source code order, so the last ones win). In strict mode, you get a syntax error. (This is one of the handy things about strict mode.)

If you have JSON text describing an object, and that JSON text duplicates property names ("keys"):

var json = '{"type": "Item", "type": "Item2", "name": "Item Name", "name": "Item Name2"}';
var data = JSON.parse(json);

...the JSON standard is silent on what should happen, but Quentin found that the RFC says the results of having non-unique property names are "unpredictable." In practice, in JavaScript, you'll only get two properties when you parse it (assuming it parses), it just depends on the deserializer/parser what values they'll have or whether the parser throws an error.

Either way, the question is moot: By the time you have an object, you have only one value for each property, which is the end result you said you want. But again, note that if you're parsing JSON, I don't think you're guaranteed which value you'll get, and so different parsers (e.g., in different browsers) may give you different results. My gut is that they'll do what JavaScript does in loose mode, but...

Fundamentally, if this is coming to you as JSON, it needs to be fixed at the end producing it. If it's source code, you just need to rename the properties or delete the ones you don't want.

Sign up to request clarification or add additional context in comments.

Comments

1

From the JSON documentation:

An object whose names are all unique is interoperable in the sense
that all software implementations receiving that object will agree on the name-value mappings. When the names within an object are not
unique, the behavior of software that receives such an object is
unpredictable. Many implementations report the last name/value pair
only. Other implementations report an error or fail to parse the
object, and some implementations report all of the name/value pairs,
including duplicates.

JavaScript will only put one of the name/value pairs in the final object.

Do not use duplicate keys.

If you need multiple values for a given name, then use an array.

{"type": ["Item", "Item2"], "name": ["Item Name", "Item Name2"]}

or

[
  {"type": "Item", "name": "Item Name"},
  {"type": "Item2" "name": "Item Name2"}
]

2 Comments

Interesting. That text is in the RFC, but not JSON.org or the ECMA standard. The RFC text you link to claims to be newer (2014, vs 2013 for the standard).
I didn't even know ECMA had done anything with JSON. The RFC is newer than ECMA-404 and says it is derived from it though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.