在Backbone集合中对类似模型进行分组

时间:2013-05-10 23:27:24

标签: javascript backbone.js

我有一个Backbone集合,我正在迭代并查找mdl.get('group')。这将返回:

[undefined, undefined, group, group, group, undefined, group, group, group, undefined, group, group]

我希望它返回的是这些组模型的数组(或集合):

[undefined, undefined, [group], undefined, [group], undefined, [group]

我正在考虑最好的方法:

  • 遍历对象
  • 返回'undefined'值而不更改它们
  • 找到具有相似值的兄弟姐妹
  • 将它们折叠为对象
  • 中的数组

与_.groupBy方法非常相似,但我需要在对象中保留模型的正确顺序。

我很想知道如何解决这个问题。到目前为止,我对如何正确解决这个问题感到磕磕绊。

谢谢!

2 个答案:

答案 0 :(得分:1)

经过一些修补,想出了这个解决方案。我扩展了Array.prototype,以便您可以轻松地将其删除。您可以使用它创建一个Underscore扩展或Collection.prototype方法:

Array.prototype.pack = function(field) {
    var result = [], target, lastItem;
    while(this.length > 0) {
        var item = this.shift();
        if(item === undefined) {
            target = result;
        } else {
            if(!lastItem || item[field] != lastItem[field]) {
                target = [];
                result.push(target);
            }
        }
        target.push(item);
        lastItem = item;
    }
    return result;
}

注意它没有经过严格测试,并且肯定可以改进,但应该给你一个想法。 您可以像这样使用它:

models.pack("name")

其中models是一个普通数组,如[undefined,{field:value}]。

尽量简洁。这里有一个工作演示:http://jsfiddle.net/YZQ6v/

答案 1 :(得分:0)

您可以使用collection.groupBy()来执行此操作。第一个groupBy“group”创建一个分组模型的哈希值,然后使用collection.map将兄弟姐妹映射到模型上。

这是一个小提琴: http://jsfiddle.net/puleos/w7drB/

var models = [
    {name: "Scott", group: "alpha"}, 
    {name: "Rose", group: "alpha"}, 
    {name: "Charles", group: "alpha"}, 
    {name: "Stan"}, 
    {name: "John"}, 
    {name: "Mary", group: "beta"}, 
    {name: "Dan", group: "beta"}, 
    {name: "Paul", group: "beta"}, 
    {name: "Grace"}, 
    {name: "Sarah", group: "omega"} 
];

var SourceCollection = Backbone.Collection.extend({});

var sourceCollection = new SourceCollection(models);
var grouped = sourceCollection.groupBy('group');

sourceCollection.map(function(model) {
  if(model.has("group")) {
      model.set({siblings: grouped[model.get("group")]});
  }
});

// sourceCollection with siblings 
console.log(sourceCollection);