Shorten an array or collection with an array of fi

2019-08-01 22:11发布

问题:

Scenario:

  • you have an array,
  • you have an array of some ids (eg: [1,3]),
  • you want to get a shortened array.

I cannot find how to do so if not in the lengthy way:

_.filter(... function (id) { return id==1 || id==3 })

Question: does such someMethod1 exist in underscore.js?

var frdsArr = 
[
 {id: 1, name: 'moe', age: 40}, 
 {id: 2, name: 'larry', age: 50}, 
 {id: 3, name: 'curly', age: 60}
];


var goodFrdsArr = _.someMethod1( frdsArr, 'id', [1, 3] );
/*
goodFrdsArr is [
 {id: 1, name: 'moe', age: 40}, 
 {id: 3, name: 'curly', age: 60}
];
*/

The same question with backbone.js: what about someMethod2?

var Friend = Backbone.Model.extend({});
var FriendsCollection = Backbone.Collection.extend({
  model: Friend
});

var friendsCollection = new FriendsCollection( frdsArr );
var goodFriendsCollection = friendsCollection.someMethod2( 'id', [1,3] );
/*
goodFriendsCollection contains 2 instances of Friend Models
*/

回答1:

Once you have found a suitable function, you can extend Underscore with _.mixin to simplify later calls. For example, you could create _.restrict to match your _.someMethod1 signature:

_.mixin({
    // filter a list on an attribute having to match a list of values
    // _.indexOf accepts an optional isSorted argument so let's pass it
    restrict: function(list, attr, values, isSorted) {

        return _.filter(list, function(obj) {
            return _.indexOf(values, obj[attr], isSorted) !== -1;
        });

    }
});

var goodFrdsArr = _.restrict(frdsArr, 'id', [1, 3]);

See http://jsfiddle.net/nikoshr/cf0qs5gh/ for a demo

With this setup, you can modify Backbone.Collection's prototype to give all your collections this new capacity (more or less taken from the Backbone source code):

Backbone.Collection.prototype.restrict = function() {
    var args = [].slice.call(arguments);
    args.unshift(this.models);
    return _.restrict.apply(_, args);
};

var friendsCollection = new Backbone.Collection(frdsArr);
var goodfriends = c.restrict('id', [1, 3]);  //an array with 2 models

http://jsfiddle.net/nikoshr/cf0qs5gh/1/



回答2:

var frdsArr = 
[
 {id: 1, name: 'moe', age: 40}, 
 {id: 2, name: 'larry', age: 50}, 
 {id: 3, name: 'curly', age: 60}
];
var filteredIDs = [1,3];
var filteredFrnds = _.filter(frdsArr, function(frnd){
return _.contains(filteredIDs, frnd.id);
})
console.log(filteredFrnds);

Make use of filter and contains

FIDDLE