我有这种数组:
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
我想将其过滤为:
var bar = [ { "a" : "1" }, { "b" : "2" }];
我尝试使用_.uniq,但是我猜因为{ "a" : "1" }
不等于它本身,所以不起作用。有什么方法可以为下划线uniq提供覆盖的equals函数吗?
{ "a" : "2" }
存在?如果是这样,是属性还是使其唯一的值?
我有这种数组:
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
我想将其过滤为:
var bar = [ { "a" : "1" }, { "b" : "2" }];
我尝试使用_.uniq,但是我猜因为{ "a" : "1" }
不等于它本身,所以不起作用。有什么方法可以为下划线uniq提供覆盖的equals函数吗?
{ "a" : "2" }
存在?如果是这样,是属性还是使其唯一的值?
Answers:
.uniq / .unique接受回调
var list = [{a:1,b:5},{a:1,c:5},{a:2},{a:3},{a:4},{a:3},{a:2}];
var uniqueList = _.uniq(list, function(item, key, a) {
return item.a;
});
// uniqueList = [Object {a=1, b=5}, Object {a=2}, Object {a=3}, Object {a=4}]
笔记:
另一个例子: 使用回调从列表中提取汽车颜色
false
不需要_.uniq()
。同样在lodash中,您可能会这样编写它_.uniq(a, 'a');
,因为它将属性赋给a
对象。
_.uniq(a, false, 'a')
)时,“'.. pluck'回调速记”才有效(例如)。因此,如果您不使用功能,请确保您拥有最新的功能。对于下划线,这可能不是问题。
如果您要根据ID删除重复项,可以执行以下操作:
var res = [
{id: 1, content: 'heeey'},
{id: 2, content: 'woah'},
{id: 1, content:'foo'},
{id: 1, content: 'heeey'},
];
var uniques = _.map(_.groupBy(res,function(doc){
return doc.id;
}),function(grouped){
return grouped[0];
});
//uniques
//[{id: 1, content: 'heeey'},{id: 2, content: 'woah'}]
Date
。但是,确实如此。
实施Shiplu的答案。
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var x = _.uniq( _.collect( foo, function( x ){
return JSON.stringify( x );
}));
console.log( x ); // returns [ { "a" : "1" }, { "b" : "2" } ]
JSON.parse(x[0]).a
,因为x不是对象的数组,它是一个字符串数组。同样,如果将b值添加到唯一值并颠倒a / b的顺序,则函数不再将它们视为唯一。(例如,““ {\” a \“:\” 1 \“,\” b \“:2}”!=“ {\” b \“:2,\” a \“:\” 1 \“} “)也许我错过了一些东西,但是结果至少应该有用吗?这是一个jsbin来说明jsbin.com/utoruz/2/edit
a
当可能存在不包含key的重复对象时,为什么只检查每个对象的key a
。但是,如果它a
是唯一的ID ,那将是有道理的。
(a ==(=) b when a = b = {a:1})
。我的答案是迭代器。我试着回答而不必担心动机,这可能是什么,对吗?(例如,也许他们想从演出中的汽车列表中提取品牌列表,颜色。jsbin.com/evodub/2/edit)干杯!
iterator
使用下划线独特的 lib跟踪对我有用,我使列表基于_id唯一,然后返回_id的字符串值:
var uniqueEntities = _.uniq(entities, function (item, key, a) {
return item._id.toString();
});
这是一个简单的解决方案,它使用深层对象比较来检查重复项(而无需求助于转换为JSON,这效率低下又很笨拙)
var newArr = _.filter(oldArr, function (element, index) {
// tests if the element has a duplicate in the rest of the array
for(index += 1; index < oldArr.length; index += 1) {
if (_.isEqual(element, oldArr[index])) {
return false;
}
}
return true;
});
如果所有元素稍后在数组中具有重复项,它将过滤掉所有元素,从而保留最后一个重复的元素。
对重复使用的测试可以_.isEqual
在两个对象之间进行优化的深度比较,有关更多信息,请参见下划线isEqual文档。
编辑:更新为使用_.filter
这是一种更清洁的方法
尝试迭代器功能
例如,您可以返回第一个元素
x = [['a',1],['b',2],['a',1]]
_.uniq(x,false,function(i){
return i[0] //'a','b'
})
=> [['a',1],['b',2]]
_.uniq(x,function(i){ return i[0]; });
这是我的解决方案(咖啡):
_.mixin
deepUniq: (coll) ->
result = []
remove_first_el_duplicates = (coll2) ->
rest = _.rest(coll2)
first = _.first(coll2)
result.push first
equalsFirst = (el) -> _.isEqual(el,first)
newColl = _.reject rest, equalsFirst
unless _.isEmpty newColl
remove_first_el_duplicates newColl
remove_first_el_duplicates(coll)
result
例:
_.deepUniq([ {a:1,b:12}, [ 2, 1, 2, 1 ], [ 1, 2, 1, 2 ],[ 2, 1, 2, 1 ], {a:1,b:12} ])
//=> [ { a: 1, b: 12 }, [ 2, 1, 2, 1 ], [ 1, 2, 1, 2 ] ]
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var bar = _.map(_.groupBy(foo, function (f) {
return JSON.stringify(f);
}), function (gr) {
return gr[0];
}
);
让我们分解一下。首先,让我们根据数组项目的字符串化值对其进行分组
var grouped = _.groupBy(foo, function (f) {
return JSON.stringify(f);
});
grouped
好像:
{
'{ "a" : "1" }' = [ { "a" : "1" } { "a" : "1" } ],
'{ "b" : "2" }' = [ { "b" : "2" } ]
}
然后让我们从每个组中获取第一个元素
var bar = _.map(grouped, function(gr)
return gr[0];
});
bar
好像:
[ { "a" : "1" }, { "b" : "2" } ]
放在一起:
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var bar = _.map(_.groupBy(foo, function (f) {
return JSON.stringify(f);
}), function (gr) {
return gr[0];
}
);