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

时间:2013-12-23 08:23:59

标签: javascript underscore.js

我有一个对象数组,我想从它获得一个新的数组,它只是基于一个属性是唯一的,有一个简单的方法来实现这个吗?

例如

[ { id: 1, name: 'bob' }, { id: 1, name: 'bill' }, { id: 1, name: 'bill' } ]

将导致2​​个对象的名称=账单被删除一次。

7 个答案:

答案 0 :(得分:61)

使用uniq功能

var destArray = _.uniq(sourceArray, function(x){
    return x.name;
});

来自文档:

  

使用===生成数组的无副本版本,以测试对象相等性。如果您事先知道数组已排序,则为isSorted传递true将运行更快的算法。如果要根据转换计算唯一项,请传递迭代器函数。

在上面的示例中,函数使用对象名称来确定唯一性。

答案 1 :(得分:8)

如果您喜欢在没有Lodash的情况下自己做事,并且没有得到详细信息,请尝试使用可选的uniq属性的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].filter(uniqFilterAccordingToProp())

答案 2 :(得分:6)

如果您想检查所有属性 lodash 4附带 _。uniqWith(sourceArray,_. isEqual)

答案 3 :(得分:3)

一种更好,更快捷的方法

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));

Found here

答案 4 :(得分:2)

您可以使用_.uniqBy功能



<link href="https://ajax.googleapis.com/ajax/libs/yui/2.9.0/build/calendar/assets/skins/sam/calendar.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.9.0/build/calendar/calendar-min.js"></script>
&#13;
var array = [ { id: 1, name: 'bob' }, { id: 2, name: 'bill' }, { id: 1, name: 'bill' },{ id: 2, name: 'bill' } ];

var filteredArray = _.uniqBy(array,function(x){ return x.id && x.name;});

console.log(filteredArray)
&#13;
&#13;
&#13;

在上面的例子中,过滤是基于属性id和amp的组合的唯一性。名。

如果您有一个对象的多个属性。 然后根据特定属性查找唯一的对象数组,您可以按照这种方法在_.uniqBy()方法中组合属性。

答案 5 :(得分:1)

如果您需要纯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

答案 6 :(得分:0)

我一直在寻找不需要库的解决方案,并将其放在一起,所以我想在这里添加它。它可能并不理想,或者在所有情况下都可以运行,但是它正在按照我的要求进行,因此可能会帮助其他人:

const uniqueBy = (items, reducer, dupeCheck = [], currentResults = []) => {
  if (!items || items.length === 0) return currentResults;
  
  const thisValue = reducer(items[0]);
  
  const resultsToPass = dupeCheck.indexOf(thisValue) === -1 ?
    [...currentResults, items[0]] : currentResults;
    
  return uniqueBy(
    items.slice(1),
    reducer,
    [...dupeCheck, thisValue],
    resultsToPass,
  );    
}

const testData = [
  {text: 'hello', image: 'yes'},
  {text: 'he'},
  {text: 'hello'},
  {text: 'hell'},
  {text: 'hello'},
  {text: 'hellop'},
];

const results = uniqueBy(
  testData,
  item => {
    return item.text
  },
)

console.dir(results)