筛选多个对象数组
Filter multiple arrays of objects
我有以下情况:
数组的数量未定义。每个数组都包含一些对象。这些对象中的每一个都有一个 id
元素,以及其他一些元素。
//Example objects:
f = [{'id': 1, 'name': 'a'}, {'id': 2, 'name': 'b'},
{'id': 3, 'name': 'c'}, {'id': 1, 'name': 'd'}, ...]
g = [{'id': 2, 'name': 'e'}, {'id': 4, 'name': 'f'},
{'id': 3, 'name': 'g'}, {'id': 4, 'name': 'h'}, ...]
h = ...
i = ...
我想过滤掉所有重复项,不仅在每个单独的数组中,而且在不同的数组中
。编辑:当两个对象的id
元素相同时,它们是重复的。优先级无关紧要,第一次出现就可以了。
我想出了以下功能:
function uniqueObjects() {
var seen = [];
for (var i=0; i<arguments.length; i++) {
var arg = arguments[i];
for (var j=0; j<arg.length; j++) {
var elm = arg[j];
var key = elm['id'];
if (seen.indexOf(key) > -1) {
arg.pop(elm);
} else {
seen.push(key);
}
}
}
return arguments;
}
但这似乎无法正常工作,因为我得到了以下值:
{'0': [{'id': 1, 'name': 'a'},
{'id': 2, 'name': 'b'},
{'id': 3, 'name': 'c'}],
'1': [{'id': 2, 'name': 'e'},
{'id': 4, 'name': 'f'}]}
主要问题在这里:
arg.pop(elm);
pop
删除数组中的最后一个元素,并且不接受任何参数。您可能的意思是:
arg.splice(j, 1);
。但是,如果您这样做,则不需要增加j
。因此,这给了我们:
function uniqueObjects() {
var seen = [];
for (var i=0; i<arguments.length; i++) {
var arg = arguments[i];
var j = 0; // **
while (j<arg.length) { // ** Made this a while loop
var elm = arg[j];
var key = elm['id'];
if (seen.indexOf(key) > -1) {
arg.splice(j, 1); // ** Remove this entry
} else {
seen.push(key);
++j; // ** Increment j
}
}
}
return arguments;
}
但是,有一种更有效的方法来跟踪您看到的id
值: 使用对象:
function uniqueObjects() {
var seen = {};
for (var i=0; i<arguments.length; i++) {
var arg = arguments[i];
var j = 0;
while (j<arg.length) {
var elm = arg[j];
var key = " " + elm['id']; // ** Note the space
if (seen[key]) { // ** Updated check
arg.splice(j, 1);
} else {
seen[key] = true; // ** Set the flag
++j;
}
}
}
return arguments;
}
创建key
时为什么要将空格放在id
之前?如果您id
具有存在于对象(如 toString
或 valueOf
)上的名称的值。(ES6 将引入Map
对象,我们不必再这样做了。
我还建议不要返回伪数组arguments
,而是使用真实数组。所以:
function uniqueObjects() {
var seen = {};
var args = Array.prototype.slice.call(arguments, 0); // <== Make real array
for (var i=0; i<args.length; i++) {
var arg = args[i];
var j = 0;
while (j<arg.length) {
var elm = arg[j];
var key = " " + elm['id']; // ** Note the space
if (seen[key]) { // ** Updated check
arg.splice(j, 1);
} else {
seen[key] = true; // ** Set the flag
++j;
}
}
}
return args;
}
现场示例:
function uniqueObjects() {
var seen = {};
var args = Array.prototype.slice.call(arguments, 0);
for (var i=0; i<args.length; i++) {
var arg = args[i];
var j = 0;
while (j<arg.length) {
var elm = arg[j];
var key = " " + elm['id']; // ** Note the space
if (seen[key]) { // ** Updated check
arg.splice(j, 1);
} else {
seen[key] = true; // ** Set the flag
++j;
}
}
}
return args;
}
var f = [
{'id': 1, 'name': 'a'}, {'id': 2, 'name': 'b'},
{'id': 3, 'name': 'c'}, {'id': 1, 'name': 'd'}
];
var g = [
{'id': 2, 'name': 'e'}, {'id': 4, 'name': 'f'},
{'id': 3, 'name': 'g'}, {'id': 4, 'name': 'h'}
];
snippet.log("Before: " + JSON.stringify([f, g]));
var result = uniqueObjects(f, g);
snippet.log("After: " + JSON.stringify(result));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
相关文章:
- 将数组对象传递到struts2中的操作类
- 如何使用jquery返回php-json数组对象
- 从其名称获取javascript数组对象
- 值未与数组对象绑定
- 如何按数组/对象值的倍数过滤对象数组
- 在表中显示数组对象
- 在数组对象中分组
- 将第二个或多个数组推送到数组对象 AngularJS 中
- 重新排列 JavaScript 数组/对象
- 键上的javascript数组对象过滤器
- handontable:在不更改数据数组/对象的情况下隐藏某些列
- 用于跟踪购物车可用性的Javascript数组/对象/哈希表
- 重建有角度的java脚本数组对象
- 对JSON数组对象进行排序
- 连接与数组对象相关的文本:方式和位置
- 哪些浏览器和版本支持将常见的类数组对象直接传递到fn.apply()
- 如何使用Handlebars循环数组对象和模板
- 是否可以引用JS数组/对象中的另一个元素
- Javascript中的名称索引-数组/对象
- 数组长度不等于数组对象