2
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?

2
  • 1
    This is not a multidimensional array. What you have is a simple array with 3 objects inside 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. Commented Nov 10, 2013 at 10:45

5 Answers 5

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
}
Sign up to request clarification or add additional context in comments.

Comments

1

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" });

3 Comments

interesting approach, but the point is the OP doesn't even know obj2. The desired result in this case would be the list of keys - ['data', 1, 'obj2'].
@Alnitak: yes, the question is a bit unclear... let the OP clarify.
ah, yes - it seems the OP does indeed know obj2 - my bad.
0

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)
  }
 }
}

Comments

0

I would recommend 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.

Comments

0

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.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.