0

Given json like this :

{ "rss": {
   "page": 1,
   "results": [{
      "type": "text",
      "$": 10
   }],
   "text": [{
      "content": "Lorem ipsum dolor sit amet.",
      "author": {
         "name": "Cesar",
         "email": "cesar@evoria.com"
      },
   },
   {
      "content": "Tema Tis rolod muspi merol.",
      "author": {
         "name": "Cleopatre",
         "email": "cleopatre@pyramid.com"
      },
   }]
}

In javascript, I can retrieve value like this :

var json = JSON.parse(datajson);
$.each(json.text, function(key, val) {
    // this one is ok
    var content = val['content'];
    // this one does not work
    var authorname = val['author.name'];
});

Is this a way, given the attribute name in a string format, to retrieve the value of a complex object, for instance json.text[0].author.name?

EDIT I would like to store the needed attributes in another object like :

[
    { dt: "Text content", dd: "content" },
    { dt: "Author name", dd: "author.name"}
]
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
enguerran
  • 3,193
  • 3
  • 26
  • 42
  • well, that might work, but in this case I need to store two strings : 'author' then 'name', when I would like to store only one representing authorname, like an xpath or a css path... – enguerran Jul 23 '12 at 14:52
  • 1
    quick and dirty var name = eval('return val.' + key + ';'); – yent Jul 23 '12 at 14:52
  • but "author" isn't a string. you can store the object and then retrieve the attributes later though. – Q2Ftb3k Jul 23 '12 at 14:54
  • 1
    If only you could downvote comments. Yikes with the eval – epascarello Jul 23 '12 at 14:54
  • 1
    This might help: http://stackoverflow.com/questions/4676223/check-if-object-member-exists-in-nested-object, btw your problem has nothing to do with JSON (or jQuery for that matter). `json` does actually not contain any JSON, but a JavaScript object. – Felix Kling Jul 23 '12 at 14:56
  • @FelixKling I tagged with `json` because I get the rss json result via a `$.get()`... But you are right, it is nothing about a json problem, but about a javascript object. – enguerran Jul 23 '12 at 15:36
  • @epascarello eval is heavy instruction, is not it? That's why you would like to downvote the comment? – enguerran Jul 23 '12 at 15:41

3 Answers3

3

You can split your "index" by . and loop over "segments", descending through levels on each iteration.

var obj = {
   author : {
      name : "AuthorName"
   }
}

function get_deep_index(obj, index) {   
   var segments = index.split('.')
   var segments_len = segments.length
   var currently_at = obj
   for(var idx = 0; idx < segments_len; idx++) {
      currently_at = currently_at[segments[idx]]
   }
   return currently_at
}

console.log(get_deep_index(obj, 'author.name'))
Oleg V. Volkov
  • 21,719
  • 4
  • 44
  • 68
2

The following should fix the problem.

var authorname = val['author']['name'];

You can also store the object itself as:

var author = val['author'];

And then later on you can index the attributes from that.

console.log(author.name, author.email)
Q2Ftb3k
  • 678
  • 3
  • 9
  • 18
  • well, that might work, but in this case I need to store two strings : 'author' then 'name', when I would like to store only one representing authorname, like an xpath or a css path... – enguerran Jul 23 '12 at 14:54
  • What does it save you by using only one string? IN the end it will be slower by having to parse it to get the data. – epascarello Jul 23 '12 at 14:57
  • There really isn't very much performance issue by indexing attributes from an object. It would be much more degrading trying to encode your already existing object as JSON and decoding later, which is what I think you want. – Q2Ftb3k Jul 23 '12 at 15:00
-2

Yent give a good hint in the comments with the eval function. I resolve my needed with this kind of code:

var json = JSON.parse(myjsonasastring);

var descriptiontobeadded = [
    { dt: "Text content", dd: "content" },
    { dt: "Author name", dd: "author.name" }
];

$.each(descriptiontobeadded, function(key, val) {
    var dt = '<dt>' + val.dt + '</dt>';
    description.append(dt);
    var dl = '<dd>' + eval('json.' + val.dd) + '</dd>';
    description.append(dl);
});
enguerran
  • 3,193
  • 3
  • 26
  • 42
  • I suggestion replacing eval with json[val.dd], much better for performance. – Q2Ftb3k Jul 23 '12 at 15:05
  • I suggest you have a look at the link I posted in my comment to your question. It seems to be what you want if you adjust a little. – Felix Kling Jul 23 '12 at 15:09
  • @FelixKling Ok, it is about the answer with a split('.') and it is a better solution than my eval deeply rejected... – enguerran Jul 23 '12 at 15:24
  • `eval` will most often yield downvotes. It is just too broad and powerful: you're leveraging entire compiler instance just to index deep structure. It is both slow and insecure. – Oleg V. Volkov Jul 23 '12 at 16:50