Javascript 如何使用下划线获得基于对象属性的唯一数组
我有一个对象数组,我想从中得到一个仅基于单个属性的唯一新数组,有没有简单的方法来实现这一点 例如 将导致两个名为“bill”的对象被删除一次。使用该函数 还是单线版Javascript 如何使用下划线获得基于对象属性的唯一数组,javascript,underscore.js,Javascript,Underscore.js,我有一个对象数组,我想从中得到一个仅基于单个属性的唯一新数组,有没有简单的方法来实现这一点 例如 将导致两个名为“bill”的对象被删除一次。使用该函数 还是单线版 var destArray = _.uniq(sourceArray, x => x.name); 从文档中: 使用===测试对象相等性,生成数组的重复自由版本。如果您事先知道数组已排序,那么为isSorted传递true将运行更快的算法。如果要基于转换计算唯一项,请传递迭代器函数 在上面的示例中,函数使用对象名称来确定唯一
var destArray = _.uniq(sourceArray, x => x.name);
从文档中:
使用===测试对象相等性,生成数组的重复自由版本。如果您事先知道数组已排序,那么为isSorted传递true将运行更快的算法。如果要基于转换计算唯一项,请传递迭代器函数
在上面的示例中,函数使用对象名称来确定唯一性。如果需要纯JavaScript解决方案:
var uniqueProperties = {};
var notUniqueArray = [ { id: 1, name: 'bob' }, { id: 1, name: 'bill' }, { id: 1, name: 'bill' } ];
for(var object in notUniqueArray){
uniqueProperties[notUniqueArray[object]['name']] = notUniqueArray[object]['id'];
}
var uniqiueArray = [];
for(var uniqueName in uniqueProperties){
uniqiueArray.push(
{id:uniqueProperties[uniqueName],name:uniqueName});
}
//uniqiueArray
如果要检查所有属性,则
lodash 4随附.uniqWith(sourceArray,.isEqual)如果您喜欢在没有lodash的情况下自己做事情,并且不会变得冗长,请使用可选的uniq by属性尝试此uniq筛选器:
const uniqFilterAccordingToProp = function (prop) {
if (prop)
return (ele, i, arr) => arr.map(ele => ele[prop]).indexOf(ele[prop]) === i
else
return (ele, i, arr) => arr.indexOf(ele) === i
}
然后,像这样使用它:
const obj = [ { id: 1, name: 'bob' }, { id: 1, name: 'bill' }, { id: 1, name: 'bill' } ]
obj.filter(uniqFilterAccordingToProp('abc'))
或者对于普通数组,只需忽略参数,同时记住调用:
[1,1,2]。过滤器(uniqFilterAccordingToProp())
您可以使用该函数
var数组=[{id:1,名称:'bob'},{id:2,名称:'bill'},{id:1,名称:'bill'},{id:2,名称:'bill'}];
var filteredArray=qby.uniqBy(数组,函数(x){return x.id&&x.name;});
console.log(filteredArray)
一种更好更快的方法
var table = [
{
a:1,
b:2
},
{
a:2,
b:3
},
{
a:1,
b:4
}
];
let result = [...new Set(table.map(item => item.a))];
document.write(JSON.stringify(result));
我正在寻找一种不需要库的解决方案,并将其放在一起,所以我想我应该将其添加到这里。它可能并不理想,或在所有情况下都能工作,但它正在做我需要的事情,因此可能会帮助其他人:
const uniqueBy=(items、reducer、dupeCheck=[],currentResults=[])=>{
如果(!items | | items.length==0)返回currentResults;
const thisValue=减速机(项目[0]);
const resultsToPass=dupeCheck.indexOf(thisValue)=-1?
[…currentResults,项[0]]:currentResults;
返回唯一(
项目。切片(1),
减速器,
[…dupeCheck,thisValue],
结果topass,
);
}
常数testData=[
{文本:'你好',图像:'是'},
{文本:'他'},
{text:'你好'},
{文本:'地狱'},
{text:'你好'},
{text:'hellop'},
];
const results=uniqueBy(
测试数据,
项目=>{
返回item.text
},
)
console.dir(results)
具有ES6的id属性的唯一数组:
arr.filter((a, i) => arr.findIndex(b => b.id === a.id) === i); // unique by id
将
b.id===a.id
替换为案例的相关比较纯Javascript解决方案。就像另一个在我看来是错误的。你认为一个属性名只会出现一次吗?@hasen我想你还不知道。在浏览器控制台中执行代码或再次阅读操作问题。您好,是否可以检查多属性上的唯一性(例如,对于上面的示例,请按id和名称进行检查?@APaul检查我给出的答案。希望您能找到实际需要的内容。对于最新版本的下划线(1.10.2),语法如下:q.uniq(array,[isSorted],[iteratee]),即您应该将函数作为第三个参数传递。请看文件lodash uniq在此中断!我花了一个小时调试。你必须使用uniqBy,因为lodash并不是下划线的替代品,它在一些事情上会自动失效。2+属性如何,但不是所有属性?@el_pup_le你能检查一下这个答案并告诉我这是否不是你所期望的。不起作用。uniqBy的回调函数需要返回该数据项唯一的值。您总是返回true,这对于任何数据项都不是唯一的。尝试此返回${x.name}/{x.id}
@BruceJo,我还提供了一个示例,用于演示解决方案,并显示了预期的行为。问题是如何基于单个属性获取唯一对象的数组。我给出的解决方案是,如果需要,通过考虑多个属性使其成为uniq。是的,这就是我理解您提出问题的方式。但是您的答案只有通过名称才能唯一x.id
总是!falsy
,所以您的返回值只是x.name
。如果您想要两个属性的唯一性,那么结果中应该有id:1,name:bill
。事实并非如此。尝试使用返回值`${x.id}/${x.name]`
你会明白我的意思的。谢谢Mudasar Rauf。不需要下划线js或任何其他库纯JavaScript。但是使用var而不是let,这样它就可以在IE或旧浏览器中工作。@SyedNasirAbbas集无论如何都不受支持。这与OP-s请求略有不同,因为它返回a
的唯一值,然而,我们应该得到表
中具有唯一a
属性的所有子项。结果的区别是[1,2]
(当前)与[{a:1,b:2},{a:2,b:3}]
(预期).@kano它正在获取第一条记录。否则,最好的解决方案是使用ColinE回答的下划线。这是一种在您知道折衷后的快速方法。它不会解决OP请求,因为它返回的是属性,而不是对象“Set”看better@sonnenhaft据我所知,Set
并没有给您以编程方式确定唯一性的选项
var table = [
{
a:1,
b:2
},
{
a:2,
b:3
},
{
a:1,
b:4
}
];
let result = [...new Set(table.map(item => item.a))];
document.write(JSON.stringify(result));
arr.filter((a, i) => arr.findIndex(b => b.id === a.id) === i); // unique by id