如何在javascripts中获得唯一的对象数组
我想得到具有唯一对象的数组 假设我有一个对象数组如何在javascripts中获得唯一的对象数组,javascript,jquery,arrays,Javascript,Jquery,Arrays,我想得到具有唯一对象的数组 假设我有一个对象数组 [{"a":"b"},{"c":"d"},{"a":"b"}] 我想要数组的唯一值,即 [{"a":"b"},{"c":"d"}] 有什么最简单的方法可以做到这一点。如果数组反复包含相同的对象,您可以这样做: var oa = {"a":"b"}, ob = {"c":"d"}; var array = [oa, ob, oa]; function unique(a) { var arr = []; for(va
[{"a":"b"},{"c":"d"},{"a":"b"}]
我想要数组的唯一值,即
[{"a":"b"},{"c":"d"}]
有什么最简单的方法可以做到这一点。如果数组反复包含相同的对象,您可以这样做:
var oa = {"a":"b"},
ob = {"c":"d"};
var array = [oa, ob, oa];
function unique(a) {
var arr = [];
for(var i = 0; i < a.length; i++) {
if( !arr.indexOf(a[i]) == -1 ) {
arr.push(a[i]);
}
}
return arr;
}
toSortedJSON = function(obj) {
return JSON.stringify(
typeof obj == "object" ?
Object.keys(obj).sort().reduce(function(o, key) {
return o[key] = toSortedJSON(obj[key]), o;
}, {}) : obj
);
}
但是:
甚至这也是事实:
var a = {a: 1},
b = a;
alert( a === b ); // true
因此,您还必须对此进行测试(这是一个浅层电容器。一层对象): 我们还必须重写我们独特的功能:
function unique(a) {
var isAdded,
arr = [];
for(var i = 0; i < a.length; i++) {
isAdded = arr.some(function(v) {
return isEqual(v, a[i]);
});
if( !isAdded ) {
arr.push(a[i]);
}
}
return arr;
}
功能唯一性(a){
var Isaded,
arr=[];
对于(变量i=0;i
完整代码:
var a=[{“a”:“b”},{“c”:“d”},{“a”:“b”}],
b=唯一(a);//[{“a”:“b”},{“c”:“d”}]
功能独特(a){
var Isaded,
arr=[];
对于(变量i=0;i
注意:某些方法的使用取决于ECMAScript第5版:
最简单的选择是通过JSON表示比较对象:
uniq = function(xs) {
var seen = {};
return xs.filter(function(x) {
var key = JSON.stringify(x);
return !(key in seen) && (seen[key] = x);
});
}
例如:
console.log(
uniq([{"a":"b"},{"c":"d"},{"a":"b"},{"a":"b"}])
)
// [{"a":"b"},{"c":"d"}]
另外,我推荐下划线.js用于此类内容,有关更多讨论和示例,请参阅
一些评论者提出了一个担忧,即当比较仅按键顺序不同的对象时,JSON.stringify
是不够的。我想这可以归结为“平等”的定义:{a:1,b:2}
和{b:2,a:1}
在一个上下文中可能被认为是平等的,而在另一个上下文中可能被认为是不同的。不过,如果您希望这些对象“相等”,可以将JSON.stringify
扩展为如下内容:
var oa = {"a":"b"},
ob = {"c":"d"};
var array = [oa, ob, oa];
function unique(a) {
var arr = [];
for(var i = 0; i < a.length; i++) {
if( !arr.indexOf(a[i]) == -1 ) {
arr.push(a[i]);
}
}
return arr;
}
toSortedJSON = function(obj) {
return JSON.stringify(
typeof obj == "object" ?
Object.keys(obj).sort().reduce(function(o, key) {
return o[key] = toSortedJSON(obj[key]), o;
}, {}) : obj
);
}
然后修改uniq以接受按键功能:
uniq = function(xs, key) {
var seen = {};
return xs.filter(function(x) {
var k = (key || JSON.stringify)(x);
return !(k in seen) && (seen[k] = 1);
});
}
最后,将自定义序列化程序传递给uniq:
console.log(
uniq([
{"a":1, "b":2},
{"x":33},
{"b":2, "a":1},
], toSortedJSON)
)
// [{"a":1,"b":2},{"x":33}]
是的,可能有。没有简单的方法做这件事——你需要用手来做。首先编写一个comparator函数,它接受2个对象,并根据对象是否相等返回true/false。然后用这个比较器在数组上循环。这不是一个重复,在这里你有一个固定的属性可以查找,在这里你没有。@harsha这不是同一个问题。在链接的问题中,通过一个特定的键检查重复性。在这里,任何对象的属性集都不是固定的,并且所有的属性都必须相等。抱歉,我的朋友,发布了错误的链接。将删除它。小心:JSON表示不可靠。在JS对象中,未定义属性的顺序
{'a':'b','c':'d'}
和{'c':'d','a':'b'}
实际上是同一个对象,但JSON表示形式可能不同。您能确定{a:1,b:1}
和{b:1,a:1}
是否以同样的方式进行字符串化?@RoToRa:请参见链接线程中的内容。@thg435也许您应该澄清一下?@NULL:添加了一些内容。
uniq = function(xs, key) {
var seen = {};
return xs.filter(function(x) {
var k = (key || JSON.stringify)(x);
return !(k in seen) && (seen[k] = 1);
});
}
console.log(
uniq([
{"a":1, "b":2},
{"x":33},
{"b":2, "a":1},
], toSortedJSON)
)
// [{"a":1,"b":2},{"x":33}]