最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavascriptjQuery: Get key by value inside a nested array - Stack Overflow

programmeradmin1浏览0评论
var myJSON =     
{"data":
    [{"obj1":"value1",
      "obj2":"value2"},

     {"obj1":"value3",
      "obj2":"value4"},

     {"obj1":"value5",
      "obj2":"value6"}]
};

I've got a multidimensional array similar to above. In the above example I can get value4 by calling data[1].obj2 - the key would be 1 in this case.

My problem: I've got value4 but I don't where it is inside the array (in terms of the key). I know value4 belongs to obj2 and I need to find it's corresponding obj1.

I'm guessing the way to solve this is to figure out what the i should be in data[i] for value4 and then simply call data[i].obj1. But how do I get that i?

var myJSON =     
{"data":
    [{"obj1":"value1",
      "obj2":"value2"},

     {"obj1":"value3",
      "obj2":"value4"},

     {"obj1":"value5",
      "obj2":"value6"}]
};

I've got a multidimensional array similar to above. In the above example I can get value4 by calling data[1].obj2 - the key would be 1 in this case.

My problem: I've got value4 but I don't where it is inside the array (in terms of the key). I know value4 belongs to obj2 and I need to find it's corresponding obj1.

I'm guessing the way to solve this is to figure out what the i should be in data[i] for value4 and then simply call data[i].obj1. But how do I get that i?

Share Improve this question asked Nov 10, 2013 at 10:40 Allen SAllen S 3,5494 gold badges39 silver badges48 bronze badges 2
  • 1 This is not a multidimensional array. What you have is a simple array with 3 objects inside – Kenneth Commented Nov 10, 2013 at 10:44
  • It's a bit abstract with this mock data, but in general you should be able to loop through the array and validate for each item if the value in "obj1" is the one you need and in that case get the corresponding "obj2" and break the loop. – GolezTrol Commented Nov 10, 2013 at 10:45
Add a ment  | 

5 Answers 5

Reset to default 3

I'm guessing the way to solve this is to figure out what the i should be in data[i] for value4 and then simply call data[i].obj1.

obj2, you mean, not obj1.

But how do I get that i?

You search for it. It's a simple loop.

var i;
for (i = 0; i < myJSON.data.length; ++i) {
    if (myJSON.data[i].obj2 === "value4") {
        // Found it
        break;
    }
}
if (i < myJSON.data.length) {
    // Found it, it's at index `i`
}

Or on a system where you can rely on ES5's forEach (either because the engine has it natively, or because you've added a shim):

var i;
myJSON.data.forEach(function(entry, index) {
    if (entry.obj2 === "value4") {
        i = index;
    }
};
if (typeof i !== "undefined") {
    // Found it
}

You can't stop a forEach early, so that does some unnecessary looping. You could use some:

var i;
myJSON.data.some(function(entry, index) {
    if (entry.obj2 === "value4") {
        i = index;
        return true; // Stops loop
    }
};
if (typeof i !== "undefined") {
    // Found it
}

Try this simple recursive function:

find = function(where, what) {
    if (typeof where != "object")
        return null;
    var matches = true;
    for (var p in what)
        matches = matches && (where[p] == what[p]);
    if (matches)
        return where;
    for (var p in where) {
        var found = find(where[p], what);
        if(found)
            return found;
    }
    return null;
}

It works with objects of any depth and allows for multiple search keys. For your example:

var data = {"data":
        [{"obj1":"value1",
            "obj2":"value2"},

            {"obj1":"value3",
                "obj2":"value4"},

            {"obj1":"value5",
                "obj2":"value6"}]
};

result = find(data, {"obj2":"value4"})
console.log(result.obj1) // value3

Another (and nicer) way to do the same is to provide a test predicate for the finder function:

find = function(where, test) {
    if (test(where))
        return where;
    if (typeof where != "object")
        return null;
    for (var p in where) {
        var found = find(where[p], test);
        if (found)
            return found;
    }
    return null;
}

result = find(data, function(x) { return x.obj2 == "value4" });

You'll have to manually trawl through your object:

for(var a=0; a<myJSON.data.length; a++)
{
 for(var b in myJSON.data[a])
 {
  if(myJSON.data[a][b]=="value4")
  {
   console.log("myJSON["+a+"]."+b)
  }
 }
}

I would remend to revise the entire data-structure, but assume that this is an abstracted example.

for(var ei in myJSON["data"]){
    if (myJSON["data"][ei]['obj2'] == "value4")){
      //ei contains the key
      //do something & break;
    }
}

Here is one-liner, although slower:

myJSON["data"].map(function(e,i){if(e["obj2"]=="value4")return e;}).filter(Boolean)[0];

or for the key:

myJSON["data"].map(function(e,i){if(e["obj2"]=="value4")return i;}).filter(Number)[0];

Also see T.J. Crowders answer using some - still slow but avoiding unnecessary cycles.

If you are using jQuery then you could use the grep function to perform your search:

var searchValue = "value4";

var result = $.grep(myJSON.data, function (e) { 
        return e.obj2 === searchValue;
    });

console.log(result[0].obj1);

See here for a working example.

发布评论

评论列表(0)

  1. 暂无评论