0

JSON object as below. Need to find the value based on user input. The input will look like "data.location.type", or "data.location.items[1].address.street". Can it be done in JQuery?

{
    "data": {
        "location": {
            "type": "List",
            "count": 1,
            "items": [
                {
                    "id": 1,
                    "type": "S",
                    "address": {
                        "street": "123 Main St",
                        "city": "New York",
                        "state": "NY"
                    }
                },
                {
                    "id": 2,
                    "type": "S",
                    "address": {
                        "street": "1323 South St",
                        "city": "New York",
                        "state": "NY"
                    }
                }
            ]
        }
    }
}
Jason P
  • 26,984
  • 3
  • 31
  • 45
user2300206
  • 73
  • 3
  • 7
  • 1
    You don't need jQuery for this, plain JS will do the trick. (And by the way, [there's no such thing as a JSON object](http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/).) – nnnnnn Oct 17 '13 at 21:02
  • jQuery, no, but javascript yes. – Kevin B Oct 17 '13 at 21:02
  • Recommended: http://stackoverflow.com/a/11657379/1026459 – Travis J Oct 17 '13 at 21:03
  • Can you please show me how to do that in javascript? I am new to JS. – user2300206 Oct 17 '13 at 21:04
  • It can be done in JavaScript. Split the input at each '.', then use each of these substrings to index into your JSON object etc.. Of course you'll need to parse the subscript syntax as well – lethal-guitar Oct 17 '13 at 21:05
  • jQuery IS javascript, folks. You're speaking as though they are completely separate things. If you're "writing jQuery", you're writing javascript. – Chris Baker Oct 17 '13 at 21:06
  • 1
    @Chris Sure. But, jQuery defines very little for regular `Object`s, leaving most of that to core ECMAScript and focusing mostly on DOM. The point is just that jQuery isn't much help here. – Jonathan Lonowski Oct 17 '13 at 21:07
  • @Chris: jQuery !== JavaScript. jQuery is *written in* JavaScript but is an API that is completely separate from the DOM API and from JavaScript's native API. – user2736012 Oct 17 '13 at 21:07
  • jQuery is a superset of javascript. You can't "write jQuery" -- you're writing javascript that uses functions defined in the jQuery library. – Chris Baker Oct 17 '13 at 21:07
  • 1
    @Chris: jQuery is NOT a superset of JavaScript. JavaScript is a language. Technically, JavaScript is an implementation and superset of ECMAScript. jQuery is just a code library. It has no language additions. It's an important distinction. – user2736012 Oct 17 '13 at 21:08
  • With all due respect, you're playing at semantics, and mostly making MY point. Jquery is a superset of javascript in the same way that SASS is a superset of CSS -- valid javascript is "valid jQuery". My comment is challenging the idea that if you're using jQuery, you're somehow not using javascript, or have to convert or do something differently. You don't, because jQuery is javascript. I don't see how you could possibly disagree with that statement. If jQuery isn't javascript, what is it? C++? Ruby? No... it's javascript. *Written in javascript*, if you insist, the two statements are equal. – Chris Baker Oct 17 '13 at 21:13
  • 1
    @Chris No. JavaScript is not jQuery ("*valid javascript is 'valid jQuery'*"). It's the other way around. And, no one's challenging that jQuery is JavaScript. They're just saying that solving this doesn't require jQuery. – Jonathan Lonowski Oct 17 '13 at 21:16
  • 1
    Well, you made a semantic argument when you "corrected" everyone by saying *"jQuery IS javascript, folks."*. No, it's not a superset of JavaScript in any meaningful way. It's a DOM abstraction with a few extra utilities at best. Everyone here knows that if you're using jQuery, you're using JavaScript. Most people, except perhaps the most pedantic, understand that when one talks of JavaScript instead of jQuery, they mean native code instead of jQuery abstractions. I already answered what jQuery is. No one said it's a different language. You're the one saying it's synonymous with a language. – user2736012 Oct 17 '13 at 21:17
  • `console.log(typeof jQuery);` logs function... so basically jQuery is just a javascript function object??? – Psych Half Oct 17 '13 at 21:19
  • @JonathanLonowski On that one point, I fully agree -- you don't need jQuery for anything. On the silly "debate" here -- if you're looking at `$('#someElement').value`, you're looking at code written in javascript. jQuery is javascript. I am not saying they are synonymous. I am saying that the distinction needn't be made to the point of telling someone who is asking "can I do this in jQuery", "no, but you can in javascript". That implies that they are different things, which they aren't. – Chris Baker Oct 17 '13 at 21:21
  • @PsychHalf Yes, jQuery is just a bunch of functions. You can write your own jQuery, it isn't anything different from what you do when you write javascript, and when you "write jQuery", you're just writing javascript and using those functions. They just took a lot of the common tasks and made aliases and wrappers. `$` wraps `document.getElementById` and some other related element-selecting native javascript. – Chris Baker Oct 17 '13 at 21:24
  • @Chris: Arguments based in pedantry. Again everyone knows that jQuery is a library written in the JavaScript language, and that uses the DOM API. To correct people in such a manner is to be willfully (one would hope) oblivious to the point being made. Such pedantry is never helpful. If we want to be that pedantic, we could also say *"Aha, `document.getElementById` are host objects, not JavaScript objects"*. But we don't do that because we're above that sort of thing. – user2736012 Oct 17 '13 at 21:26
  • @user2736012 you say "everyone knows", and yet here is someone in this very thread who does NOT know. And the confusion is caused by stuff like this: when the OP said "Can I do X in jQuery", people come along and say, "No, but you can do it in javascript". That is the misnomer I sought to correct... I'm not sure what your angle is, but in case you can't tell, I do know what I'm doing ;) – Chris Baker Oct 17 '13 at 21:27
  • @Chris yep... write less do more.. me like jQuery.. :D – Psych Half Oct 17 '13 at 21:32
  • @Chris: jQuery is an API. jQuery's API has no facility for string manipulation. JavaScript's standard library does. So when one says "no, but you can with JavaScript", it's terribly clear that they're describing what can or can not be done with jQuery's API. *That's* the distinction. – user2736012 Oct 17 '13 at 21:38
  • 2
    You could not do this in jQuery because it would require you to use javascript's API. The jQuery API **does not support this**. Where in the jQuery API is the function that says give me an object and a string and I will return a value? If that exists then you can do this with jQuery, and if it does not, then you cannot. It is very straightforward and that is the nature of APIs. Can the API for Math manipulate the DOM? Then no, you cannot manipulate the DOM with Math. – Travis J Oct 17 '13 at 21:38
  • There's no such thing as jQuery standalone, and I guess that's completely where I'm coming from. While I appreciate that explanation of the comment *"No, but you can in JavaScript"*, I think it creates the impression that jQuery is an independent entity by itself. If someone were trying to manipulate the DOM with the Math API, as @TravisJ put forth, you wouldn't say "You can't do that with Math, but you can do that with javascript." You would simply say, "you aren't doing it right". The distinction between "writing jQuery" and "writing javascript" doesn't need to be made, I think it confuses. – Chris Baker Oct 17 '13 at 21:41
  • As @user2736012, again, I know what jQuery is. I don't think it was clear as it stood, otherwise I wouldn't have made a comment. You've since taken it upon yourself to argue that comment ad naseum, and I'm not sure why. But, I don't need you to explain it to me anymore, nor did I ever. I think we're done here. – Chris Baker Oct 17 '13 at 21:42
  • @Chris: No one made the argument that jQuery is standalone, nor that it's another language. I never said you don't know what it is. I'm saying you're making a fruitless point when you correct people who point out the very real distinction that needs to be made. – user2736012 Oct 17 '13 at 21:43
  • I think the distinction is fruitless, and that's why I commented. – Chris Baker Oct 17 '13 at 21:45
  • 1
    @Chris Ok, you inform them that they're "*not doing it right*." But, that's not helpful on its own. "*In what way? What's 'not right' about it?*" And, you're back to the very distinction you're suggesting is pointless because your alternative is just as vague as describing the problem with "*It's not working.*" – Jonathan Lonowski Oct 17 '13 at 21:46
  • 2
    @Chris comes home from the grocery store with a bag of cookies. Chris' wife says, *"What's this? I sent you to get sugar, eggs, etc..."* Chris replies *"Honey, cookies ARE sugar, eggs, etc..."*. Chris sleeps on the couch that night. – user2736012 Oct 17 '13 at 21:46
  • Now you're being ridiculous. Great. Adieu. – Chris Baker Oct 17 '13 at 21:47
  • @Chris: If the distinction is fruitless, then you really *don't* know what jQuery is. – user2736012 Oct 17 '13 at 21:47
  • Yeah, you're right. Guess my entire career has just been a random and long case of good luck. – Chris Baker Oct 17 '13 at 21:48
  • @Chris: If you can't see a distinction between a 3rd party API written in an language and the actual language and its API, then it would cause one to wonder. – user2736012 Oct 17 '13 at 21:51
  • Look, I'll take a crack at this one more time, but it doesn't matter to me if you two dudes from the internet understand my point. I don't need you to. When a new developer is having trouble with their script, and asks, "Can I do this in jQuery", they are asking, rather, "how do I do this." The reply, "you cannot do that in jQuery" leads the new developer to believe that something that is possible in javascript is NOT possible "in jquery". Since "in jquery" doesn't really exist, you've made a fruitless distinction in the mind of that developer. That's why I commented. – Chris Baker Oct 17 '13 at 21:52
  • You being smug towards me doesn't change my point, make it less valid, or make yours more valid. It just makes you seem like a jerk that I don't want to converse with. Am I questioning your knowledge or experience? No. I would appreciate it if you would have a little more respect. – Chris Baker Oct 17 '13 at 21:54
  • "in jQuery" does exist. jQuery is defined by its documented API. That's why *I* commented. – user2736012 Oct 17 '13 at 21:54
  • "in Jquery" does NOT exist. If you are using the jQuery API, you are "in javascript" every bit as much as if you weren't using the jQuery API. You're creating a boundary that does not exist. – Chris Baker Oct 17 '13 at 21:55
  • *You* brought up the idea of knowledge and experience with *" Guess my entire career has just been a random and long case of good luck."*. I just followed that. – user2736012 Oct 17 '13 at 21:55
  • In code: http://jsfiddle.net/YB49g/ -- you are not "in jQuery" or "not in jQuery" -- the distinction is a false one. I brought up my career and experience because you're speaking down to me as though I don't know what jQuery is. I could MAKE jQuery. Isn't it far more likely that you're misunderstanding me, or simply disagree with the approach, considering that I am an experienced developer? – Chris Baker Oct 17 '13 at 21:56
  • If you can't acknowledge the existence of something being "in jQuery" meaning "using its documented API", then I wouldn't know *what* to do with you. Again, no one has claimed that one is not using JavaScript. The point is that one is not using jQuery to do the needed string manipulation. – user2736012 Oct 17 '13 at 21:58
  • And if YOU can't acknowledge that the distinction could and does confuse some new developers, such as the type that ask questions here, then I don't know what to do with you. The statement, "no, not in jQuery, but you can do it in javascript" implies exactly that one is not using javascript when one is using jQuery. You create a fruitless distinction. – Chris Baker Oct 17 '13 at 22:00
  • Blah blah blah. The comment wasn't for you. Disagree with it if you want. – Chris Baker Oct 17 '13 at 22:01
  • @Chris: I can certainly acknowledge that a new developer could be confused for any number of reasons, including overly terse and incomplete statements like "jQuery IS JavaScript". And so I do disagree. Was that unclear? – user2736012 Oct 17 '13 at 22:06

2 Answers2

2

First you're going to need to parse it to an object then use an object lookup function like the one below (here's a fiddle of it in action http://jsfiddle.net/C8zH2/):

//https://gist.github.com/megawac/6162481#file-underscore-lookup-js
var lookup = function(obj, key) {
    var type = typeof key;
    if (type == 'string' || type == "number") key = ("" + key).replace(/\[(.*?)\]/, function(m, key){//handle case where [1] may occur
        return '.' + key;
    }).split('.');
    for (var i = 0, l = key.length, currentkey; i < l; i++) {
        if (obj.hasOwnProperty(key[i])) obj = obj[key[i]];
        else return undefined;
    }
    return obj;
}

//syntax: lookup(jsonobj, input);
//Tests using your data
lookup(data, "data.location.type") //=> "List"
lookup(data, "data.location.items[1].address.street") //=> ""1323 South St"
megawac
  • 10,953
  • 5
  • 40
  • 61
  • How does that lookup function resolve the subscript (`items[1]`)? I don't see that in there, it's just looking for `'.'` – lethal-guitar Oct 17 '13 at 21:12
  • Ya I didnt actually handle that case – megawac Oct 17 '13 at 21:14
  • Then you should remove the `items.1.address` as well, it won't behave as stated in your comment – lethal-guitar Oct 17 '13 at 21:15
  • @lethal-guitar Yeah I just checked and it will because its calling items["1"] – megawac Oct 17 '13 at 21:17
  • That's right, missed that. Doesn't really help the OP anyway. Another thing: There is an extraneous closing brace here: `[i]))` It should be just one – lethal-guitar Oct 17 '13 at 21:18
  • Well he can just do a regex test like `key[i] = key[i].match(/\[(.*?)\]/)[1] || key[i]` or something if he wants to handle that case – megawac Oct 17 '13 at 21:20
  • Updated to handle the cases for square braces and tested code it works I'll update your fiddle in a sec – megawac Oct 17 '13 at 21:27
  • try the sample. but display "undefined" while using alert ("value is " + lookup(data, "data.location.type"); – user2300206 Oct 17 '13 at 21:56
  • I just updated the fiddle with your test - it works (were u missing a bracket?) http://jsfiddle.net/C8zH2/1/ – megawac Oct 17 '13 at 22:05
  • @user2300206 sorry but why does this function not suit your needs – megawac Oct 17 '13 at 22:26
  • @megawac your solution works. If the input string looks like "location.type", what change do I need to make? – user2300206 Oct 19 '13 at 03:59
  • you mean instead of data.location.type? – megawac Oct 19 '13 at 04:27
  • If you want it to work with or without 'data' you can do something along: `var prop = lookup(inputstr.replace(/data\./, "") + "[data]");` which will prepend "data." to whatever they want to search. Note that this will break if they just look up `"data"` or if they want to search something other than `data`. – megawac Oct 19 '13 at 05:20
  • Change that replace to `var prop = lookup(inputstr.replace(/data\.|^/, "[data]");` bit nicer ;)\ – megawac Oct 19 '13 at 05:31
1

This is just thrown together, but it should work for you...

http://jsfiddle.net/E2hEh/2/

var input = "data.location.type";
//var input = "data.location.items[1].address.street";
var parts = input.split('.');

var prev;
for(var i = 0; i < parts.length; i++){
    var index;
    if(parts[i].indexOf('[') != -1){
        var key = parts[i].substr(0, parts[i].indexOf('['));
        index = parseInt(parts[i].substr(parts[i].indexOf('[') + 1, 1), 10);
        if(!prev){
            prev = test[key][index];
        } else {
            prev = prev[key][index];
        }
    } else { 
        if(!prev){
            prev = test[parts[i]];
        } else {
            prev = prev[parts[i]];
        }

        if(i === parts.length - 1){
            alert(prev);
        }
    }
}
Tom Bowers
  • 4,951
  • 3
  • 30
  • 43