I want to create an array of specific attribute values from a Backbone collection.
var days = _.select(
this.collection.models,
function(model) {
return model.attributes.type === 'session';
}
);
days = _.pluck(days, 'attributes'),
days = _.pluck(days, 'date');
This works, but seems inefficient. Is there a way to accomplish the same thing without having to define days
three times?
pluck is a convenience method that wraps map
, and map
is available directly on the collection, which should make this easier.
assuming you are trying to get the date
attribute out of your models, you can do this:
days = this.collection.map(function(model){
return model.get('date');
});
your select call is also available on the collection directly, as the filter
method.
days = this.collection.filter(function(model){
return model.attributes.type === 'session';
});
you can chain these two together, but it helps if you define methods separately:
var sessionFilter = function(model){
return model.attributes.type === 'session';
};
var getDate = function(model){ return model.get('date'); }
days = this.collection.filter(sessionFilter).map(getDate);
this should return the results your looking for... or something close to this at least :)
I should have read the docs more carefully. In addition to the pluck
method in underscore, backbone collections also have a pluck
method.
http://documentcloud.github.com/backbone/#Collection-pluck
So, my solution would be
//Assumme 'collection' is a backbone collection
collection.pluck('date');
I still need to figure out how to best combine with filtering - perhaps using ideas from @Derick's answer, but this answers the meat of my own question.
I think this could work :
var days =
_( this.collection.where({ type : "session" }))
.chain()
.pluck("attributes")
.pluck("date")
.value()
Slightly more elegant, but still close to unreadable, in my opinion.
Have the same question, and figured out a better solution. I might have just taken advantage of new features in underscore, since it's 2013 now :)
var days = _.invoke(this.collection.where({type : 'session'}), 'get', 'date');
This is functionally the same as Derick's answer using _.chain()
var days = _(this.collection.models)
.chain()
.filter(function(model){return model.attributes.type === 'session';})
.pluck('date')
.value();