下划线/洛达什由多个属性唯一
underscore/lodash unique by multiple properties
我有一个重复的对象数组,我正在尝试获取一个唯一的列表,其中唯一性由对象属性的子集定义。例如
{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} });
但这行不通。我可以做类似的事情吗,或者如果我比较多个属性,我是否需要创建对象的可比较表示形式?
使用 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
不幸的是,似乎没有一种简单的方法可以做到这一点。如果不为此编写自己的函数,则需要返回可以直接比较相等性的内容(如第一个示例所示(。
一种方法是只.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']));
});
请记住,就属性顺序而言,对象不是确定性的,因此您可能只想坚持使用显式数组方法。
附言将 uniqBy
替换为 uniq
的 Lodash <4
这里有正确的答案
JavaScript - Lodash - 基于多个属性创建一个唯一的列表。
仅供参考var result = _.uniqBy(list, v => [v.id, v.sequence].join());
晚了,但我在 lodash 文档中找到了这个。
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.uniqWith(objects, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
我确实认为 join(( 方法仍然是最简单的。尽管在前面的解决方案中提出了问题,但我认为选择正确的分隔符是避免已识别陷阱的关键(不同的值集返回相同的连接值(。请记住,分隔符不必是单个字符,它可以是您确信不会在数据本身中自然出现的任何字符串。我一直这样做,并且喜欢使用"~!$~"作为我的分隔符。它还可以包含特殊字符,如 ''t''r' 等。
如果包含的数据确实是不可预测的,也许最大长度是已知的,您可以在连接之前简单地将每个元素填充到其最大长度。
@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'
。通过将 a + b 组合成一个字符串,我可以得到一个唯一的键来检查。
{ a: 4, b: 'cat', d: 'generic', id: `${a}-${b}` }. // id is now '4-cat'
注: 您显然需要在创建对象期间映射数据或执行此操作,因为您无法在同一对象中引用对象的属性。
现在比较很简单...
_.uniqBy(animalArray, 'id');
生成的数组长度为 3,它将删除最后一个重复项。
- ng重复中的ng模型-初始化唯一作用域属性
- JavaScript-用唯一属性标识对象
- “new”关键字是在构造对象时自动设置“constructor”属性的唯一方法吗
- Ember JS如何获取具有唯一属性值的数组
- 角度:当您需要“跟踪”但您没有唯一的属性可以跟踪时,您会怎么做
- 动态删除没有唯一属性的输入字段
- 基于单个属性从数组中获取唯一对象
- 使用jQuery隐藏具有非唯一属性的元素
- Knockout.js中使用的唯一ID;对于“;单选按钮组中的标签属性
- Backbone.js在permalink集合中所有模型的唯一属性名称
- 如何检查具有唯一值的相同属性的同一类
- 页面上第二个表单所需的唯一 id 属性
- Lodash Javascript 基于唯一属性值返回元素
- 基于两个属性从 javascript 中的对象数组中获取唯一数组
- 如何使用 Wolfpack.js 测试我的 Sails.js 模型的唯一电子邮件属性
- 克隆元素,但它们必须具有“唯一属性”
- 未捕获的异常:每个数据元素都必须实现一个唯一的“id”属性slick.dataview.js
- 如何使Javascript数组按属性唯一
- 下划线/洛达什由多个属性唯一
- 识别数组中具有与另一个对象数组中属性唯一的对象的最快方法