Как вырезать атрибут коллекции Backbone

Я хочу создать массив конкретных значений атрибутов из коллекции Backbone.

var days = _.select(
    this.collection.models,
    function(model) {
        return model.attributes.type === 'session';
    }
);

days = _.pluck(days, 'attributes'),
days = _.pluck(days,'date');

Это работает, но кажется неэффективным. Есть ли способ выполнить одно и то же, не задавая days три раза?

Ответы

Ответ 1

pluck - метод удобства, который обертывает map, а map доступен непосредственно в коллекции, что должно сделать это проще.

Предполагая, что вы пытаетесь получить атрибут date из своих моделей, вы можете сделать это:

days = this.collection.map(function(model){
  return model.get('date');
});

ваш вызов выбора также доступен в коллекции напрямую, как метод filter.

days = this.collection.filter(function(model){ 
  return model.attributes.type === 'session'; 
});

вы можете связать эти два вместе, но это помогает, если вы определяете методы отдельно:

var sessionFilter = function(model){
  return model.attributes.type === 'session'; 
};
var getDate = function(model){ return model.get('date'); }

days = this.collection.filter(sessionFilter).map(getDate);

это должно вернуть результаты, которые вы ищете... или что-то близкое к этому, по крайней мере:)

Ответ 2

Я должен был внимательно прочитать документы. В дополнение к методу pluck в подчёркнутом виде, у базовых коллекций также есть метод pluck.

http://documentcloud.github.com/backbone/#Collection-pluck

Итак, мое решение будет

//Assumme 'collection' is a backbone collection
collection.pluck('date');

Мне все еще нужно выяснить, как лучше всего комбинировать фильтрацию - возможно, используя идеи из ответа @Derick, но это отвечает на мясо моего собственного вопроса.

Ответ 3

Я думаю, это может сработать:

var days =
    _( this.collection.where({ type : "session" }))
    .chain()
    .pluck("attributes")
    .pluck("date")
    .value()

Чуть более элегантный, но по-прежнему близкий к нечитабельному, на мой взгляд.

Ответ 4

Иметь тот же вопрос, и выдумал лучшее решение. Возможно, я просто воспользовался новыми функциями в подчеркивании, так как это 2013 сейчас:)

var days = _.invoke(this.collection.where({type : 'session'}), 'get', 'date');

Ответ 5

Это функционально то же самое, что и ответ Derick, используя _. chain()

var days = _(this.collection.models)
            .chain()
            .filter(function(model){return model.attributes.type === 'session';})
            .pluck('date')
            .value();