【问题标题】:How to remove the same object in two arrays with lodash or underscore?如何使用 lodash 或下划线删除两个数组中的相同对象?
【发布时间】:2015-05-27 04:13:41
【问题描述】:

现在我有两个对象数组,

var arr1 = [{id: 0, name: 'Jack'}, {id: 1, name: 'Ben'}, {id: 2, name: 'Leon'}, {id: 3, name: 'Gavin'}];
var arr2 =  [{id: 0, name: 'Jack'}, {id: 5, name: 'Jet'}, {id: 2, name: 'Leon'}];

我想删除arr1和arr2中相同id的那些对象,所以结果是:

var arr1 = [{id: 1, name: 'Ben'}, {id: 3, name: 'Gavin'}];
var arr2 =  [{id: 5, name: 'Jet'}];

如何用lodash或underscore实现?

这是我的实现。

arr1_ids = _.pluck(arr1, 'id');
arr2_ids = _.pluck(arr2, 'id');

same_ids = _.intersection(arr1_ids, arr2_ids);

arr1 = _.remove(arr1, function(e) { return !_.contains(same_ids, e.id); });
arr2 = _.remove(arr2, function(e) { return !_.contains(same_ids, e.id); });

有没有更好的方法来做到这一点?

【问题讨论】:

  • 这不能用.uniq来完成吗?
  • 如何使用uniq做到这一点?
  • 定义“更好”。是不是更快?代码少?更容易维护? ;-)

标签: javascript arrays underscore.js lodash


【解决方案1】:

你能用 _.difference 吗?

same_elements = _.intersection(arr1, arr2);
arr1 = _.difference(arr1, same_elements);
arr2 = _.difference(arr2, same_elements);

【讨论】:

  • 我认为.intersection() 不会正确比较内部对象。
  • @Ja͢ck 然后使用_.intersectionBy() 或_.intersectionWith()。
  • _.intersectionBy(arr1, arr2, 'id') 绝对有效——我只是用它来完成同样的操作。
【解决方案2】:

我不确定应该如何使用下划线或 lodash 来完成,但这里有一个 JavaScript 实现。

它会创建一个过滤器函数,然后您可以将其应用于两个数组以仅保留不属于交集的元素。

var arr1 = [{id: 0, name: 'Jack'}, {id: 1, name: 'Ben'}, {id: 2, name: 'Leon'}, {id: 3, name: 'Gavin'}];
var arr2 =  [{id: 0, name: 'Jack'}, {id: 5, name: 'Jet'}, {id: 2, name: 'Leon'}];

var negative_intersection_filter = function(a, b) {
  // create a map to speed up the filtering later
  var map = a.reduce(function(map, current) {
    // perform the intersection
    map[current.id] = b.some(function(item) {
      return item.id == current.id;
    });
    return map;
  }, {});

  // our filtering function, simple
  return function(item) {
    return !map[item.id];
  }
}(arr1, arr2);

// apply the filter here
arr1 = arr1.filter(negative_intersection_filter);
arr2 = arr2.filter(negative_intersection_filter);
console.log(arr1);
console.log(arr2);

【讨论】:

    【解决方案3】:

    我认为您的算法是正确的,这是纯 js 中略有不同的方法。为简洁起见,我使用了a, b 而不是arr1, arr2:

    // Collect ids and sort
    var ids = a.map(function(obj) {return obj.id}).concat(b.map(function(obj) {return obj.id})).sort();
    
    // Get IDs that aren't duplicates
    var nonDups = ids.filter(function(v, i, o){return v !== o[i-1] && v !== o[i+1]});
    
    // Keep only the non-duplicates in each array
    a.reduceRight(function(pre, cur, i, o){if (nonDups.indexOf(cur.id) == -1) o.splice(i, 1)},0);
    b.reduceRight(function(pre, cur, i, o){if (nonDups.indexOf(cur.id) == -1) o.splice(i, 1)},0);
    
    JSON.stringify(a)  // [{"id":1,"name":"Ben"},{"id":3,"name":"Gavin"}]
    JSON.stringify(b)  // [{"id":5,"name":"Jet"}]
    

    reduceRight 只是用来向后迭代每个数组,这样拼接就不会影响迭代。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2021-01-06
      • 2018-01-15
      • 2015-05-05
      • 2015-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多