删除Javascript中带下划线的重复对象
我有这种数组:删除Javascript中带下划线的重复对象,javascript,json,underscore.js,Javascript,Json,Underscore.js,我有这种数组: var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ]; 我希望对其进行过滤,使其具有: var bar = [ { "a" : "1" }, { "b" : "2" }]; 我尝试使用uq.uniq,但我想是因为{a:“1”}不等于它本身,所以它不起作用。有没有办法为Underline uniq提供覆盖的equals函数?实现Shiplu的答案 var foo = [ { "a" : "1" }, { "b" :
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
我希望对其进行过滤,使其具有:
var bar = [ { "a" : "1" }, { "b" : "2" }];
我尝试使用uq.uniq,但我想是因为
{a:“1”}
不等于它本身,所以它不起作用。有没有办法为Underline uniq提供覆盖的equals函数?实现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" } ]
.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}]
注:
如果您希望根据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'}]
尝试迭代器函数
例如,您可以返回第一个元素
x = [['a',1],['b',2],['a',1]]
_.uniq(x,false,function(i){
return i[0] //'a','b'
})
=>[[a',1],[b',2]]
下面是一个简单的解决方案,它使用深度对象比较来检查重复项(而不需要转换为JSON,这既低效又粗糙)
var newArr=\过滤器(oldArr,函数(元素,索引){
//测试元素在数组的其余部分中是否有重复项
对于(索引+=1;索引
如果以后在数组中有一个重复的元素,它会过滤掉所有元素,这样就保留了最后一个重复的元素
重复的测试使用。.isEqual
在两个对象之间执行优化的深度比较。有关更多信息,请参阅
编辑:更新为使用。过滤器,这是一种更干净的方法
以下是我的解决方案(coffeescript):
例如:
_.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 ] ]
当我有一个属性id时,这是我首选的下划线方式:
var x = [{i:2}, {i:2, x:42}, {i:4}, {i:3}];
_.chain(x).indexBy("i").values().value();
// > [{i:2, x:42}, {i:4}, {i:3}]
使用下划线时,我必须在iteratee函数中使用String()
function isUniq(item) {
return String(item.user);
}
var myUniqArray = _.uniq(myArray, isUniq);
使用lib following对我有效,我基于_id使列表唯一,然后返回_id的字符串值:
var uniqueEntities = _.uniq(entities, function (item, key, a) {
return item._id.toString();
});
您可以通过以下方式进行速记:
_.uniq(foo,‘a’)
lodash 4.6.1文档将此作为对象键相等的示例:
\uqwith(对象,\uq.isEqual)代码>
我想用一种简单的写作方式来解决这个简单的解决方案,同时也有一点计算开销的痛苦。。。但这不是一个具有最小变量定义的简单解决方案吗
function uniq(ArrayObjects){
var out = []
ArrayObjects.map(obj => {
if(_.every(out, outobj => !_.isEqual(obj, outobj))) out.push(obj)
})
return out
}
让我们把它分解一下。首先,让我们根据字符串化值对数组项进行分组
var grouped = _.groupBy(foo, function (f) {
return JSON.stringify(f);
});
分组的
看起来像:
{
'{ "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];
}
);
请同时发布您的代码。是否存在类似于
{“a”:“2”}
的内容?如果是这样的话,是属性还是值使它唯一?是的,我确实有一个属性作为键,我实现了别人在另一个主题上给我的索引,但后来我想用一些常见的库来清理我的代码。Spleae change accepted Response。\uq.uniq()
不需要false
。同样在lodash中,您也可以这样编写uq.uniq(a,'a')
,因为它会在对象上提取属性a
。只有当您为isSorted传递一个值时,“.pulk”回调速记”才起作用(例如\uUq.uniq(a,false,'a')
)我ping了github/bestiejs/lodash,他们说这个问题已经解决了。因此,如果您没有使用函数,请确保您拥有最新的。这可能不是下划线的问题。迭代器听起来不是一个好名字,它是一个类似哈希的函数,用于确定每个对象的标识。编辑后使用回调与lodash文档更一致:)例如,您可以进行更新。(1) Makes:u(cars).uniq('make').map('make').valueOf()和(2)颜色:u(cars).uniq('color').map('color').valueOf()。你可以脱色,做封口。(所有这些,如果你升级德洛达斯使用)顺便问一句,你是如何得到4票?要获得结果的属性,必须将每个数组值还原回一个对象。类似于JSON.parse(x[0]).a
,因为x不是对象数组,而是字符串数组。此外,如果将b值添加到unique并反转a/b的顺序,则函数不再认为它们是唯一的。(例如,“{\'a\':\'1\',\'b\':2}”!=“{\'b\':2,\'a\':\'1\'”)也许我遗漏了什么,但结果至少应该有用吗?这里有一个jsbin来说明您是对的,具有相同密钥但顺序不同的情况会破坏实现。但是我不确定为什么您只检查每个对象的键a
,而可能存在不包含键a
的重复对象。然而,如果a
是一个唯一的id,这是有意义的。当我回答这个问题时,我觉得问题的重点是覆盖(a==(=)b,当a=b={a:1})
。我回答的重点是迭代器。我试着回答而不担心动机,动机可能是什么,对吧?(例如,可能他们想从展会上的汽车列表中提取品牌、颜色列表。)干杯!此外,我认为当有人提出一个问题提供动机时,它有助于我们给出简洁的答案。这是一场比赛,所以我更愿意站在第一位,并在必要时澄清。圣帕特里克日快乐。我刚刚又投了一票,因为这回答了我关于比较嵌套数组的问题。我只是想知道如何重写迭代器。秒参数实际上是可选的,你也可以做.uniq(x,函数(i){returni[0];})代码>不依赖于具有预定义的唯一属性?我喜欢。这是一个很好的解决方案,适用于小型对象数组,但与提供uniq id相比,循环中的循环成本较高。您的解决方案不适用于对象数组,但仅适用于数组当
{
'{ "a" : "1" }' = [ { "a" : "1" } { "a" : "1" } ],
'{ "b" : "2" }' = [ { "b" : "2" } ]
}
var bar = _.map(grouped, function(gr)
return gr[0];
});
var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];
var bar = _.map(_.groupBy(foo, function (f) {
return JSON.stringify(f);
}), function (gr) {
return gr[0];
}
);