过滤对象集合以获取值数组

时间:2012-08-24 14:14:17

标签: javascript backbone.js twitter-bootstrap underscore.js

实际上这个问题与先行引导有关 因为我需要使用自动完成功能定义要在输入文本中显示的值数组。

无论如何,目标只是定义一个读取对象数组并返回字符串数组的函数。 这是我的代码(1)。

(1)的目标是: 1)从一组对象中获取一个字符串数组。 2)过滤这个数组,拒绝一些元素。

它不起作用,因为我要拒绝的元素在数组中持续存在。 实际上在自动完成中我得到了错误的值,实际上它会破坏代码,因为typeahead不期望false。

如何修复代码并改进代码?


(1)

element.typeahead({
    source: function ( {
        var users = _.map(app.userCollection.models, function (model) {
            if (model.get('id') === app.currentUser.id) {
                return false;
            }
            return model.get('first_name') + ' ' + model.get('last_name');
        });
        console.log(users); // [false, 'some name'];
        _.reject(users, function(name) {
            return name  === false;
        });
        console.log(users); // [false, 'some name'];
                            // why does the false value persist?
        return users;
    }
});

1 个答案:

答案 0 :(得分:4)

下划线方法通常不会对数组本身进行操作,但它们返回一个新数组,但我建议单独检查每个函数的下划线docs以进行确认。在这种情况下,我们可以安全地假设拒绝返回一些新数组,根据下划线docs中的这句话:

  

返回list中的值,不包含真值测试(迭代器)传递的元素。

您目前正在做的是:

_.reject(users, function(name) {
  return name  === false;
});

因此,您实际上并未将结果保存在任何地方。要保留对数组的引用而不使用不需要的元素,请执行以下操作:

users = _.reject(users, function(name) {
  return name  === false;
});

那会产生你想要的结果,但是让我给你一个重构提示:

尽可能使用骨干自己的方法,它将使代码更具可读性

source: function() {
  // filter the collection down to the users you want
  var users = app.userCollection.filter(function(model) {
    return model.id === app.currentUser.id;
  });
  // -> users is now an array of models

  // use map to transform each wanted user to a string giving its full name
  users = _.map(users, function(user) {
    return user.get('first_name')+' '+user.get('last_name');
  });
  // -> users is now an array of strings

  return users;
}

希望这有帮助!