Javascript 从对象数组中获取唯一元素数组
我有如下数组:Javascript 从对象数组中获取唯一元素数组,javascript,arrays,underscore.js,unique,union,Javascript,Arrays,Underscore.js,Unique,Union,我有如下数组: files = [ {name: 'Lorem', other: true}, {name: 'Foo', other: true}, {name: 'Bar', other: true} ]; files = [ {name: 'Lorem', other: true}, {name: 'Xxxxx', other: true} ]; files = [ {nam
files = [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Bar', other: true}
];
files = [
{name: 'Lorem', other: true},
{name: 'Xxxxx', other: true}
];
files = [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Epic', other: true},
{name: 'Xxxxx', other: true}
];
我试图得到一个带有下划线的唯一元素的合并数组,但它不起作用。这是我的密码:
function getAllFiles(alldocs) {
var all = [];
_.each(alldocs, function(element) {
all = _.union(all, element.files);
});
return all;
}
但是我得到了一个包含重复项的数组。纯Java的解决方案使用临时对象和
var files1=[{name:'Lorem',other:true},{name:'Foo',other:true},{name:'Bar',other:true}],
files2=[{name:'Lorem',other:true},{name:'Xxxxx',other:true}],
结果=函数(数组){
变量o={},r=[];
array.forEach(函数(a){
如果(!(o中的a.名称)){
o[a.name]=a;
r、 推(o[a.name]);
}
});
返回r;
}(files1.concat(files2));
document.write(“”+JSON.stringify(结果,0,4)+“”)代码>纯Javascrift中的解决方案临时对象和
var files1=[{name:'Lorem',other:true},{name:'Foo',other:true},{name:'Bar',other:true}],
files2=[{name:'Lorem',other:true},{name:'Xxxxx',other:true}],
结果=函数(数组){
变量o={},r=[];
array.forEach(函数(a){
如果(!(o中的a.名称)){
o[a.name]=a;
r、 推(o[a.name]);
}
});
返回r;
}(files1.concat(files2));
document.write(“”+JSON.stringify(结果,0,4)+“”)代码>使用lodash,您可以使用\uqby
files = _.chain(files).indexBy("name").values();
使用lodash,您可以使用\uqby
files = _.chain(files).indexBy("name").values();
这是因为您使用的是对象数组,下划线不知道在比较项目时使用哪个对象属性(例如名称、其他),
以下是一个干净的解决方案:
files1 = [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Bar', other: true}
];
files2 = [
{name: 'Lorem', other: true},
{name: 'Xxxxx', other: true}
];
files3 = [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Epic', other: true},
{name: 'Xxxxx', other: true}
];
//append all json
all = _.union(files1,files2, files3);
//get unique by define function which returns name (deciding factor for unique)
all = _.uniq(all, function(d){return d.name});
console.log(all);//prints the unique elements
这是因为您使用的是对象数组,下划线不知道在比较项目时使用哪个对象属性(例如名称、其他),
以下是一个干净的解决方案:
files1 = [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Bar', other: true}
];
files2 = [
{name: 'Lorem', other: true},
{name: 'Xxxxx', other: true}
];
files3 = [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Epic', other: true},
{name: 'Xxxxx', other: true}
];
//append all json
all = _.union(files1,files2, files3);
//get unique by define function which returns name (deciding factor for unique)
all = _.uniq(all, function(d){return d.name});
console.log(all);//prints the unique elements
使用下划线可以执行以下操作:
function getAllFiles(alldocs) {
var union = _.union.apply(null, alldocs.map(function(v) {
return v.files;
}));
return _.uniq(union, function(v) {
return JSON.stringify(v);
});
}
var alldocs = [
{files: [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Bar', other: true}
]},
{files: [
{name: 'Lorem', other: true},
{name: 'Xxxxx', other: true}
]},
{files: [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Epic', other: true},
{name: 'Xxxxx', other: true}
]}
];
var result = getAllFiles(alldocs);
工作代码使用下划线可以如下操作:
function getAllFiles(alldocs) {
var union = _.union.apply(null, alldocs.map(function(v) {
return v.files;
}));
return _.uniq(union, function(v) {
return JSON.stringify(v);
});
}
var alldocs = [
{files: [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Bar', other: true}
]},
{files: [
{name: 'Lorem', other: true},
{name: 'Xxxxx', other: true}
]},
{files: [
{name: 'Lorem', other: true},
{name: 'Foo', other: true},
{name: 'Epic', other: true},
{name: 'Xxxxx', other: true}
]}
];
var result = getAllFiles(alldocs);
工作代码您需要在调用union
后应用方法
问题是uniq
默认情况下使用=
操作符来测试数组元素的相等性。因此,如果您有一个对象数组,那么每个对象都将按引用进行比较,而不是按值进行比较,这显然是不希望的行为。这个问题可以通过向uniq提供额外的参数回调函数(iteratee
)来解决,该函数将数组元素转换为简单的可比较值。在您的例子中,可以使用JSON.stringify
方法返回对象的字符串表示形式
您需要在调用union
后应用方法
问题是uniq
默认情况下使用=
操作符来测试数组元素的相等性。因此,如果您有一个对象数组,那么每个对象都将按引用进行比较,而不是按值进行比较,这显然是不希望的行为。这个问题可以通过向uniq提供额外的参数回调函数(iteratee
)来解决,该函数将数组元素转换为简单的可比较值。在您的例子中,可以使用JSON.stringify
方法返回对象的字符串表示形式
请看,您可能还可以将下面给出的解决方案与union一起使用,它们都只检查“name”属性,但您可能希望区分“name”和“other”属性。在阵列上循环并检查两个。如果只是要检查的单个值,则可以使用映射并减少一行。请参阅,您可能还可以使用union
下面给出的解决方案仅检查“name”属性,但您可能希望区分“name”和“other”属性。在阵列上循环并检查两个。如果只是要检查的单个值,可以使用贴图并减少一条直线。