javascript - lodash - 基于多个属性创建唯一列表

San*_*ath 9 javascript unique underscore.js lodash

我的收藏看起来像这样.

  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}];
Run Code Online (Sandbox Code Playgroud)

我试图获得一个唯一的列表,以便具有相同id和序列的对象将只返回一个对象(我们在这里有2个 - {id:'12349',序列:1})

我的代码

  var uniqueList = _.uniq(list, function(obj) {
    return obj.id && obj.sequence;
  });
Run Code Online (Sandbox Code Playgroud)

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

rye*_*lar 26

可以使用uniqBy()来计算,通过该生成的列表的标准,其中,所述iteratee回调返回的加入值idsequence所述保藏的各项目.当您只希望将特定属性作为唯一性标准时,下面的解决方案非常有用,尤其是当集合中的每个对象不仅具有idsequence属性时.

var result = _.uniqBy(list, v => [v.id, v.sequence].join());
Run Code Online (Sandbox Code Playgroud)

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>');
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>
Run Code Online (Sandbox Code Playgroud)

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

var result = _.uniqBy(list, v => JSON.stringify([v.id, v.sequence]));
Run Code Online (Sandbox Code Playgroud)

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>');
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>
Run Code Online (Sandbox Code Playgroud)

更新:

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

var result = _.uniq(list, v => [v.id, v.sequence].join());
Run Code Online (Sandbox Code Playgroud)

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>');
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
Run Code Online (Sandbox Code Playgroud)

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

var result = _.uniq(list, v => JSON.stringify([v.id, v.sequence]));
Run Code Online (Sandbox Code Playgroud)

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>');
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
Run Code Online (Sandbox Code Playgroud)