0

I need to write a filter function that will allow me to query by nested object, like this:

var data = [
             { twitter: { id: 1, name: "Bob" } },
             { twitter: { id: 2, name: "Jones" } }
           ],
    query = { 'twitter.id': 1 };

# Perform filter using data and query variables
var search = …

console.log(search);
> ["0"]

The filter should return an array of indexes that match the query.

I currently have this working without nested object support at http://jsbin.com/umeros/2/edit.

However, I would like to be able to query for nested objects, such as the query seen above.

  • Check out [this post](http://stackoverflow.com/a/14397052/1048572), you can choose a duplicate for free. – Bergi Feb 24 '13 at 21:18
  • check this library http://jsonselect.org/#overview – jcubic Feb 24 '13 at 21:18
  • That doesn't help @Bergi. –  Feb 24 '13 at 21:19
  • @OliverJosephAsh: Why not? [Convert string in dot notation to get the object reference](http://stackoverflow.com/questions/10934664/convert-string-in-dot-notation-to-get-the-object-reference) is exactly what you want. – Bergi Feb 24 '13 at 21:21
  • @Bergi It explains how to convert the string into dot notation but that doesn't help me write the filter function. –  Feb 24 '13 at 21:23

1 Answers1

1

Using the function ref from this answer, your filter should look like this:

var search = _.filter(_.keys(data), function (key) {
    var obj = data[key];
    return _.every(query, function (val, queryKey) {
        return ref(obj, queryKey) === val;
    });
});
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • This will only work for one property in `query`: http://jsbin.com/uqabog/1/edit. Can you think of a solution that will work with multiple properties in `query`? –  Feb 24 '13 at 22:31
  • I'm a bit confused now (sorry) but I seem to have got it working in ES5 (which is what I started with): http://jsbin.com/umeros/9/edit. Thanks. –  Feb 24 '13 at 22:39
  • [It does for multiple](http://jsbin.com/uqabog/3/edit). Only `every` expects you to return `true`, otherwise it breaks the loop since it already knows that *not every* item fulfils the condition. – Bergi Feb 24 '13 at 22:43
  • Yeah, that's the ES5 variant. Only you tagged your question [tag:Underscore.js], so I used the cross-browser functions (and `_.every` works directly on objects as well) – Bergi Feb 24 '13 at 22:45
  • What can I do to prevent it erroring when `data` contains an object that does not match the `query`? I.e. http://jsbin.com/umeros/11/edit –  Feb 24 '13 at 22:52
  • Use a function like [this](http://stackoverflow.com/a/6491621/1048572) that can handle the case of non-existing properties. – Bergi Feb 24 '13 at 23:09