Javascript 如何使用下划线获得基于对象属性的唯一数组

Javascript 如何使用下划线获得基于对象属性的唯一数组,javascript,underscore.js,Javascript,Underscore.js,我有一个对象数组,我想从中得到一个仅基于单个属性的唯一新数组,有没有简单的方法来实现这一点 例如 将导致两个名为“bill”的对象被删除一次。使用该函数 还是单线版 var destArray = _.uniq(sourceArray, x => x.name); 从文档中: 使用===测试对象相等性,生成数组的重复自由版本。如果您事先知道数组已排序,那么为isSorted传递true将运行更快的算法。如果要基于转换计算唯一项,请传递迭代器函数 在上面的示例中,函数使用对象名称来确定唯一

我有一个对象数组,我想从中得到一个仅基于单个属性的唯一新数组,有没有简单的方法来实现这一点

例如

将导致两个名为“bill”的对象被删除一次。

使用该函数

还是单线版

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