我有一个带有重复项的对象数组,我试图获得一个唯一的列表,其中唯一性由对象属性的子集定义。例如,
{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} });
但这并不奏效。是否有类似我可以做的事情,或者如果我要比较多个属性,我是否需要创建对象的可比较表示?
答案 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
时,这些项目被视为重复项,并且只有第一个出现的项才会包含在新数组中。
示例:
我有一个包含latitude
和longitude
的位置列表-其中一些是相同的-我想查看唯一位置列表:
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' },
];
在上面的示例中,我希望数组由a
和b
唯一,但是现在我有两个对象分别为a: 4
和b: 'cat'
。通过将+ b组合成字符串,我可以获得一个唯一的密钥来进行检查。
{ a: 4, b: 'cat', d: 'generic', id: `${a}-${b}` }. // id is now '4-cat'
注意:您显然需要映射数据或在对象创建期间执行此操作,因为您无法引用同一对象内的对象属性。
现在比较很简单...
_.uniqBy(animalArray, 'id');
结果数组的长度为3,它将删除最后一个重复项。