Returning a collection list filtered from an array

by Cedric Dugas on September 12, 2011

One thing I was trying to figure out lately is if it was possible to filter a collection from an array of id’s. Imagine you got a task model that lists another sub-task model. In your task model you got an array of sub-tasks, [1,4,7]. How would you go to retrieve those models?

The loop

The easiest way of doing this is by looping the array and saving the models one by one in a new collection.The code in your view would look like something like this:

var currentSubtask = new SubtaskCollection;
_.each(this.model.toJSON().subtasksArray, function(taskID){
	var mySubTask = allSubTasks.getOne(taskID)

When we are about to show the sub-tasks for a master task, we loop our sub-tasks array and retrieve the sub-tasks one by one.

In our sub-tasks collection declaration, we would have this filter:

	getOne : function(SubTaskid){
		return this.filter(function(data) {
		  	return data.get("id") == SubTaskid;

Easy, we get one model each time. Obviously this technique is really not the most efficient. What we really want to achieve is not having to loop through our sub-tasks array on the view side, but directly pitch the array in the collection filter.

A better way

To do this we will have to change our filter, what we will do is check if each model through our collection exists in our sub-tasks array. If its not, its going to return -1 and in that case we are not going to keep it.

	getGuestById : function(subtasksArray){
		    return (_.indexOf(subtasksArray, model.get("id")) > -1);

This will return a list of models that you can add to a collection. We could also return a collection of those models directly wrapping everything with _()

	getGuestById : function(subtasksArray){
		return _({
		    return (_.indexOf(subtasksArray, model.get("id")) > -1);

That’s it

Here we go for filtering with arrays, in my next article I will use this technique to “bind” 2 models together and handle small relationships.