views:

76

answers:

3

What the question says...

Does jQuery have any methods that will allow you to query a mult-dimensional array of objects in a similar fashion as it does with the DOM.

So for instance, get me a list of objects contained within a multi-dimensional array having some matching property value - for instance where StartOfPeriod greater than a specified date or where name == "Ben Alabaster"

I'd like to avoid re-inventing the wheel if there's something already out there.

+4  A: 

You can't use selector syntax, but jQuery comes with $.grep and $.inArray, which can be useful for this. grep returns a new array of elements that match a predicate. inArray returns the index of the first matching element, or -1. For instance:

var matches = $.grep(array, function(el){
  return el.StartOfPeriod > 2000;
});

These are similar to the standard ECMAScript methods, Array.filter (simimlar to grep) and Array.indexOf (similar to inArray); jQuery actually uses Array.indexOf where available. There are also other useful ECMAScript methods, such as Array.every (all elements matching) and Array.some (at least one matching). MDC has code you can add to your project so these work in browsers that don't have native implementations.

Matthew Flaschen
That works nicely on single dimension arrays, and I'd already considered this, and I could use it as the basis for a plugin, but I just wondered if there was something already existing that handled multi-dimensional arrays - i.e. 2D, 3D etc
BenAlabaster
+2  A: 

You may find a plugin, but not in the jQuery core. There are a few helpful array methods: each, unique, inArray. In combination, you could create something custom to meet your needs.

What you are searching for is more of a set library with xpath like traversal. Prototype has a much larger set of array methods. But still probably wouldn't meet your exact needs out of the box.

I agree with alex, such a library/extension would be interesting.

Jason McCreary
I'm considering writing said extension, but I don't want to reinvent the wheel unnecessarily.
BenAlabaster
This would definitely be an awesome extension. I might start writing in my *snicker* spare time.
Ryan Kinal
@Ryan Kinal: Just find an excuse to need one for one of your clients ;) I'm just trying to figure out what I want the selector syntax to look like, probably just like the regular syntax. If you do get as far as coding something, maybe we can bounce some ideas off each other.
BenAlabaster
@BenAlabaster Indeed!
Ryan Kinal
@Ryan Kinal - I've got parts 1 and 2 working, I've got the filter function plugged into jQuery and functioning, just need to figure out how to use set it up to use selector syntax now.
BenAlabaster
I'm working on the design for something. I don't know whether I'll actually get it into code, but who knows. I have this question favorited, so I'll be checking back every so often.
Ryan Kinal
+1  A: 

I just wrote this.. I think it works properly but it could definitely get cleaned up :)

function findMatchingObjects(obj, member, value){
   var final = new Array();
   var temp = new Array();
   for(var p in obj){
    if (typeof obj[p] == 'object' ) {
     temp = findMatchingObjects(obj[p], member, value);
     if (temp.length == 1)
      final.push(temp[0]);
    }
    if (p == member && obj[p] == value) {
     final.push(obj);
    }
   }
   alert(final.length);
   return final;
}

Use it like so:

var moo ={baz: 1, boo: 2, bar:{c1: 3, c2: 4, c3:{t:true, f:false, baz:1}},d: 11};
var foo = findMatchingObjects(moo, "baz", 1);

// did it work?
console.log(foo);

Returns an array of object (or sub-objects) that match the member-value pair. In this case, foo contains both moo and c3 since both of the objects contain a baz = 1 pair.

Making the function look and feel like a jQuery selector is just a matter of syntactic sugar.

David Titarenco
I've got something very similar knocked up too, I'm just trying to mod it so that I can plug it into jQuery with selector syntax. I've not written any jQuery plugins before though, so I'm just trying to wrap my head around that.
BenAlabaster