Search code examples
backbone.jsunderscore.js

How to filter collection based on another collection using underscore.js


I have a collection called `mainItems``

this.mainItems;

which contains 18 models. And also one more collection object which contains selected items:

this.seletedItems;

I need to filter the main collection object based on other collection.

I have tried the below approach:

    var that = this;
    var model = _.reject(that.filteredItems.models, function(model1){
        return _.filter(that.collection.models, function(model2) {
           return model1.id == model2.id;
        });
    });

but this approach is not working properly. Is it possible to filter the main items by avoiding second iteration ?

Please help!


Solution

  • You can use the Underscore's methods proxied by Backbone to simplify your filter.

    For example, to list the models in mainItems without the models in selectedItems, you could use

    // reject the models found in selectedItems
    var filtered = mainItems.reject(function(m) {
        return selectedItems.get(m.id);
    });
    

    Note that Collection.get is a hash lookup, making this a Backbone equivalent to the answer pointed by @GruffBunny in the comments.

    And a demo

    var mainItems = new Backbone.Collection([
        {id: 1},
        {id: 2},
        {id: 3},
        {id: 4}
    ]);
    
    var selectedItems = new Backbone.Collection([
        {id: 2}
    ]);
    
    var keep = mainItems.reject(function(m) {
        return selectedItems.get(m.id);
    });
    
    console.log(_.pluck(keep, 'id'));
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>