【问题标题】:javascript - lodash - create a unique list based on multiple attributesjavascript - lodash - 基于多个属性创建唯一列表
【发布时间】:2016-09-15 22:02:11
【问题描述】:

我的收藏看起来像这样。

  var list = [{id:'12345', sequence:null}, {id:'12346', sequence:null}, {id:'12347', sequence:null}, {id:'12348', sequence:1}, {id:'12348', sequence:2}, {id:'12349', sequence:1}, {id:'12349', sequence:1}];

我正在尝试获取一个唯一列表,以便具有相同 id AND 序列的对象仅返回其中一个对象(我们这里有 2 个 - {id:'12349', sequence:1})

我的代码

  var uniqueList = _.uniq(list, function(obj) {
    return obj.id && obj.sequence;
  });

我们可以像这样使用 lodash uniq 吗?解决这个问题的方法是什么?

【问题讨论】:

  • 我的项目使用 lodash 3,因此 _.uniqWith 和 _.uniqBy 不能使用。

标签: javascript underscore.js unique lodash


【解决方案1】:

您可以使用uniqBy() 计算生成列表的标准,其中迭代回调返回集合中每个项目的idsequence 的联合值。当您只想将特定属性作为唯一性标准时,下面的解决方案非常有效,尤其是当您的集合中的每个对象可能不仅具有 idsequence 属性时。

var result = _.uniqBy(list, v => [v.id, v.sequence].join());

var list = [{
  id: '12345',
  sequence: null
}, {
  id: '12346',
  sequence: null
}, {
  id: '12347',
  sequence: null
}, {
  id: '12348',
  sequence: 1
}, {
  id: '12348',
  sequence: 2
}, {
  id: '12349',
  sequence: 1
}, {
  id: '12349',
  sequence: 1
}, {
  id: '123490',
  sequence: 1,
  extra: 1
}, {
  id: '123490',
  sequence: 1,
  extra: 2
}];

var result = _(list)
  .uniqBy(v => [v.id, v.sequence].join())
  .value();

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"&gt;&lt;/script&gt;

或者,如果您的属性包含要用作标准的非原始值(对象或数组),那么您仍然可以使用上面的解决方案,但要加入值数组,您必须使用JSON.stringify()

var result = _.uniqBy(list, v => JSON.stringify([v.id, v.sequence]));

var list = [{
  id: '12345',
  sequence: null
}, {
  id: '12346',
  sequence: null
}, {
  id: '12347',
  sequence: null
}, {
  id: '12348',
  sequence: 1
}, {
  id: '12348',
  sequence: 2
}, {
  id: '12349',
  sequence: 1
}, {
  id: '12349',
  sequence: 1
}, {
  id: '123490',
  sequence: 1,
  extra: 1
}, {
  id: '123490',
  sequence: 1,
  extra: 2
}];

var result = _.uniqBy(list, v => JSON.stringify([v.id, v.sequence]));

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"&gt;&lt;/script&gt;

更新:

对于 lodash3 解决方案,对于具有原始值的属性,您仍然可以使用第一个解决方案中的模式 uniq()

var result = _.uniq(list, v => [v.id, v.sequence].join());

var list = [{
  id: '12345',
  sequence: null
}, {
  id: '12346',
  sequence: null
}, {
  id: '12347',
  sequence: null
}, {
  id: '12348',
  sequence: 1
}, {
  id: '12348',
  sequence: 2
}, {
  id: '12349',
  sequence: 1
}, {
  id: '12349',
  sequence: 1
}, {
  id: '123490',
  sequence: 1,
  extra: 1
}, {
  id: '123490',
  sequence: 1,
  extra: 2
}];

var result = _.uniq(list, v => [v.id, v.sequence].join());

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"&gt;&lt;/script&gt;

对于非原始属性,您仍然可以使用上面的第二个示例 uniq()

var result = _.uniq(list, v => JSON.stringify([v.id, v.sequence]));

var list = [{
  id: '12345',
  sequence: null
}, {
  id: '12346',
  sequence: null
}, {
  id: '12347',
  sequence: null
}, {
  id: '12348',
  sequence: 1
}, {
  id: '12348',
  sequence: 2
}, {
  id: '12349',
  sequence: 1
}, {
  id: '12349',
  sequence: 1
}, {
  id: '123490',
  sequence: 1,
  extra: 1
}, {
  id: '123490',
  sequence: 1,
  extra: 2
}];

var result = _.uniq(list, v => JSON.stringify([v.id, v.sequence]));

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"&gt;&lt;/script&gt;

【讨论】:

  • 感谢您的精彩回答。遗憾的是,我的项目使用 lodash 3,因此无法使用 UniqWith 和 UniqBy。看来我必须为此使用纯javascript。
  • 当 [id,sequence] 类似于 [1,23] 和 [12,3] 时会发生什么 - 两者都返回正确?
【解决方案2】:

您可以使用uniqWith

这个方法和 _.uniq 类似,只是它接受比较器来比较数组的元素。比较器使用两个参数调用:(arrVal, othVal)。

isEqual

在两个值之间执行深度比较以确定它们是否相等。

_.uniqWith(list, _.isEqual);

【讨论】:

    【解决方案3】:

    不。使用uniqWith。并使用与isEqual 相同的签名编写正确的比较器。

    【讨论】:

      猜你喜欢
      • 2016-02-20
      • 1970-01-01
      • 2019-05-19
      • 2014-12-06
      • 2022-01-22
      • 2019-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多