下划线/ lodash由多个属性唯一

时间:2014-10-10 19:09:35

标签: javascript underscore.js unique lodash

我有一个带有重复项的对象数组,我试图获得一个唯一的列表,其中唯一性由对象属性的子集定义。例如,

{a:"1",b:"1",c:"2"}

我想在唯一性比较中忽略c

我可以做类似

的事情
_.uniq(myArray,function(element) { return element.a + "_" + element+b});

我希望我能做到

_.uniq(myArray,function(element) { return {a:element.a, b:element.b} });

但这并不奏效。是否有类似我可以做的事情,或者如果我要比较多个属性,我是否需要创建对象的可比较表示?​​

5 个答案:

答案 0 :(得分:28)

遗憾的是,似乎没有一种直接的方法可以做到这一点。如果没有为此编写自己的函数,则需要返回可以直接比较相等的内容(如第一个示例所示)。

一种方法就是.join()您需要的属性:

_.uniqBy(myArray, function(elem) { return [elem.a, elem.b].join(); });

或者,您可以使用_.pick_.omit删除您不需要的内容。从那里开始,您可以将_.values.join()一起使用,甚至只使用JSON.stringify

_.uniqBy(myArray, function(elem) {
    return JSON.stringify(_.pick(elem, ['a', 'b']));
});

请记住,就属性顺序而言,对象不是确定性的,因此您可能只想坚持使用显式数组方法。

P.S。将uniqBy替换为uniq Lodash< 4

答案 1 :(得分:1)

我认为join()方法仍然是最简单的。尽管在之前的解决方案中引起了关注,但我认为选择正确的分隔符是避免识别出的陷阱的关键(不同的值集返回相同的连接值)。请记住,分隔符不必是单个字符,它可以是您确信不会在数据本身中自然发生的任何字符串。我一直这样做,喜欢使用'〜!$〜'作为我的分隔符。它还可以包含特殊字符,如\ t \ r \ n等。

如果包含的数据真的不可预测,可能已知最大长度,您可以在加入前简单地将每个元素填充到其最大长度。

答案 2 :(得分:1)

这是正确的答案

javascript - lodash - create a unique list based on multiple attributes

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

答案 3 :(得分:0)

使用Lodash的uniqWith方法:

_.uniqWith(array, [comparator])

  

此方法类似于_.uniq,但它接受comparator,该方法被调用来比较array的元素。结果值的顺序取决于它们在数组中出现的顺序。比较器由两个参数调用:(arrVal,othVal)

comparator返回true时,这些项目被视为重复项,并且只有第一个出现的项才会包含在新数组中。


示例:
我有一个包含latitudelongitude的位置列表-其中一些是相同的-我想查看唯一位置列表:

const locations = [
  {
    name: "Office 1",
    latitude: -30,
    longitude: -30
  },
  {
    name: "Office 2",
    latitude: -30,
    longitude: 10
  },
  {
    name: "Office 3",
    latitude: -30,
    longitude: 10
  }
];

const uniqueLocations = _.uniqWith(
  locations,
  (locationA, locationB) =>
    locationA.latitude === locationB.latitude &&
    locationA.longitude === locationB.longitude
);

// Result has Office 1 and Office 2

答案 4 :(得分:0)

@voithos和@Danail组合答案中有一个提示。我解决这个问题的方法是在数组中的对象上添加唯一键。

开始采样数据

const animalArray = [
  { a: 4, b: 'cat', d: 'generic' },
  { a: 5, b: 'cat', d: 'generic' },
  { a: 4, b: 'dog', d: 'generic' },
  { a: 4, b: 'cat', d: 'generic' },
];

在上面的示例中,我希望数组由ab唯一,但是现在我有两个对象分别为a: 4b: 'cat'。通过将+ b组合成字符串,我可以获得一个唯一的密钥来进行检查。

{ a: 4, b: 'cat', d: 'generic', id: `${a}-${b}` }. // id is now '4-cat'

注意:您显然需要映射数据或在对象创建期间执行此操作,因为您无法引用同一对象内的对象属性。

现在比较很简单...

_.uniqBy(animalArray, 'id');

结果数组的长度为3,它将删除最后一个重复项。