【问题标题】:How to modify select objects in a JSON collection w/lodash如何使用 lodash 修改 JSON 集合中的选择对象
【发布时间】:2015-05-03 12:52:06
【问题描述】:

我正在寻找一种基于引用数组中存在的记录 ID 来更新集合中选定记录的高效方法。例如,给定一个 [1,2,5] 的引用数组,我希望集合中具有这些 ID 的每条记录都具有$selected: true 的属性。集合中的每条记录都将与视图中的复选框相关联,$selected 项目将被选中 (fiddle)

我已经开始使用下面的方法(coffeescript),但我是 Lodash 的新手,所以我想我会寻求一些反馈。另外,我不确定将$selected: false 设置为备用记录的最干净的方法是什么?

# Whole Collection
collection = [
    {id:1, name: "one"},
    {id:2, name: "two"},
    {id:3, name: "three"},
    {id:4, name: "four"},
    {id:5, name: "five"}
]

# Mark subset as selected
for id in [1,2,5]
    _.where( collection, 'id':id ).forEach( (record) ->
        record.$selected = true
    )

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


编辑 添加了对双向绑定 $selected 元素到视图中复选框的引用

【问题讨论】:

    标签: json coffeescript underscore.js lodash


    【解决方案1】:

    我会做这样的事情(对不起,它不是 CoffeScript,但你明白了):

    var collection = [
        { id:1, name: 'one' },
        { id:2, name: 'two' },
        { id:3, name: 'three' },
        { id:4, name: 'four' },
        { id:5, name: 'five'}
    ];
    
    var ids = [ 1, 2, 5 ];
    
    _(collection)
        .indexBy('id')
        .at(ids)
        .each(_.ary(_.partialRight(_.assign, { $selected: true }), 1))
        .value();
    
    console.log(collection);
    // → 
    // [
    //   { id: 1, name: 'one', $selected: true },
    //   { id: 2, name: 'two', $selected: true },
    //   { id: 3, name: 'three' },
    //   { id: 4, name: 'four' },
    //   { id: 5, name: 'five', $selected: true }    
    // ]
    

    首先,我们使用indexBy() 创建一个中间对象。键是collection 中的id 值。接下来,我们将我们感兴趣的 id 传递给 at()。这将构建一个新集合,其中仅包含我们所追求的 id。

    最后一步是使用each() 添加$selected 属性。这是通过组合partialRight()assign()ary() 来完成的。部分应用的参数是新的$selected 属性。我们使用ary() 来确保传递给each() 的回调只有一个参数。

    【讨论】:

    • 感谢您回复@Adam Boduch!我在上一篇文章中没有提到的一点是,我想装饰原始收藏而不是返回其中的一个子集(抱歉,我不清楚这一点)。我在我的应用程序中使用 Angular 并依靠两种方式数据绑定将 $selected 项目映射到复选框。我已经更新了小提琴,所以希望它更有意义......jsfiddle.net/zd78e4bj
    • @Brian,我已经更新了我的答案。现在它将就地更新集合。让我知道这是否是你所追求的。
    【解决方案2】:

    您可以使用 mapforEach 函数在 Lodash 或原生 JavaScript 中完成所有这些操作。 Map 创建一个新列表,forEach 将改变现有列表。

    这些的关键是转换函数。如果$selected 在ids 集合中存在或不存在,此函数会将其设置为true 或false。

    function mark(item) {
        item['$selected'] = (ids.indexOf(item.id) > -1);
        return item;
    }
    

    您可以使用以下方法构建更通用的转换器:

    function markItemByList(list, property, searchField) {
        return function(item) {
            item[property] = (list.indexOf(item[searchField]) > -1);
            return item;
        }
    }
    

    Coffeescript 将是:

    markItemByList = (list, property, searchField) ->
        (item) ->
            item[property] = (list.indexOf(item[searchField])) > -1)
            item
    

    如果你想要一个可变的实现:

    function select(ids, collection) {
        collection.forEach(markItemByList(ids, '$selected', 'id'));
    }
    

    这是一个 lodash 不可变的实现:

    function select(ids, collection) {
        return _.map(collection, markItemByList(ids, '$selected', 'id'));
    }
    

    这是一个纯 JavaScript 不可变实现:

    function select(ids, collection) {
        return collection.map(markItemByList(ids, '$selected', 'id'));
    }
    

    这是一个角度实现:

    angular.forEach(collection, markItemsByList(ids, '$selected', 'id'));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-31
      • 2023-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多