14

I have the following json, I don't have any control over this output unfortunately.

{
"questions": {
    "9733": {
        "text": "Star Trek or Star Wars?",
        "answers": {
            "41003": "Star Trek",
            "41004": "Star Wars",
            "41005": "Neither is superior in my opinion; both great in their own ways",
            "41006": "Not a fan",
            "41007": "I don't have an opinion on this"
        }
    },
    "25272": {
        "text": "Which of these summer movies are you looking forward to the most?",
        "answers": {
            "99545": "World War Z",
            "99546": "Monsters University ",
            "99547": "White House Down",
            "99548": "Man of Steel",
            "99549": "Lone Ranger",
            "99550": "The Wolverine"
        }
    },
    "27547": {
        "text": "Should the U.S. attack Syria?",
        "answers": {
            "107453": "Yes",
            "107454": "No"
        }
    }
}
}

I am using json.parse to parse this. To get the text of the first question I would normally do something like this.

var jsonData = JSON.parse(data);//Where data = the json above
console.log(jsonData.questions.9733.text);//Obviously this fails

However javascript doesn't like that number in there obviously. How would you recommend accessing the text of the first question? I would prefer the json to be setup better with in an array of questions instead. Unfortunately I don't have any control over the output of this JSON.

I'm also not going to be aware of the what the keys are as they come across, but thats a whole other issue. I'm willing entertain any suggestions on how to parse this thing as I've never had to parse such a strange JSON output.

Caimen
  • 2,623
  • 2
  • 26
  • 43
  • 1
    I would just use `jsonData['questions']['9733']['text']` – NullUserException May 08 '14 at 21:20
  • 1
    `jsonData.questions[9733].text` should work. `foo.bar` and `foo['bar']` are equivalent in JS. – IMSoP May 08 '14 at 21:20
  • Since I've been working on javascript, every little issue I have to Google. Nothing is intuitive here. Why can't it be simply `jsonData.questions.9733.text` don't know. – Atul Mar 24 '22 at 09:08
  • @Atul it's crazy how i get comments on posts that are 8 years old. But the reason is json should never be formatted in the way you see above. It's very poor decision making with who ever created the json format you see above, not any particular problem with javascript. The object should have been formatted as an array, not a series of random objects strung together. – Caimen Apr 07 '22 at 18:54

5 Answers5

14

You need to use bracket notation:

console.log(jsonData.questions["9733"].text);

But because the value inside the brackets will be automatically converted a string, this would also work:

console.log(jsonData.questions[9733].text);

Note however, that using non-strings is as property names generally bad form and could lead to some subtle problems, e.g. if the property name was "001", then [001] would not work.

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • Property names are cast into strings, so your last example wouldn't work just because `001` gets converted to `"1"` rather than `"001"` – NullUserException May 08 '14 at 21:24
  • 1
    @NullUserException No, actually it doesn't (at least, not in Opera/Chrome). I get "undefined" when attempting the last example as a number, but the actual data when I convert it to a string. – Cypher May 08 '14 at 21:27
  • @NullUserException The last example works as described (`if the property name was "001", then [001] would not work.`), at least in Opera & Chrome. :) – Cypher May 08 '14 at 21:30
  • @Cypher Yes, as it should. – NullUserException May 08 '14 at 21:33
  • Thanks for the help, I appreciate it. I may end up contacting the creator of the API and suggesting the use of arrays instead of numbers as keys. It would make my life much easier. – Caimen May 08 '14 at 21:36
2

I believe you can access the data via same syntax as in an array:

console.log(jsonData.questions[9733].text);
Tohveli
  • 487
  • 5
  • 18
  • 1
    @sabof I didn't say it's an array, but that the syntax is same. – Tohveli May 08 '14 at 21:24
  • 1
    @NullUserException Granted, there are times when this will fail (see p.s.w.g's answer), but in this particular case it does work. I don't see how that makes this answer "wrong". – Cypher May 08 '14 at 21:28
  • 3
    I think the objection here is in the specific language "*as in **any** array*", which might be read as suggesting that the object is in fact an array. I don't think that's what Tohveli meant, but a more clear way of wording it would be "*as in **an** array*". – p.s.w.g May 08 '14 at 21:32
  • 1
    I removed the downvote. But note that there's a caveat in using this syntax with numbers rather than strings (`var[123]` vs `var["123"]`). See @p.s.w.g's answer. – NullUserException May 08 '14 at 21:43
2

Why don't you try?

jsonData["questions"]["9733"]

How to access a numeric property?

Community
  • 1
  • 1
VictorR
  • 31
  • 6
1

If you have to use numbers as keys... you can access them like this:

var text = jsonData.questions["9733"].text;

Edit: You can also access it with the number 9733. It doesn't have to be a string. Only needs to be a string if the key is non-numeric.

Kyle Paulsen
  • 956
  • 1
  • 8
  • 22
-1

Try using Ason, If you are using Java 8. Gradle dependency compile 'org.arivu:ason:1.0.3'.

Java code as follows

Ason ason = new Ason();
Object json = ason.fromJson("<<JSON String!>>");
System.out.println(Ason.getJson(json, "questions.9733.text", null)):
parthipang
  • 1
  • 1
  • 1
  • 1
    Just so you know you need to look at the tags in the question to make sure you understand which language is being utilized. In this case the tag is javascript and not java. – Caimen Jan 02 '18 at 02:16