过滤多个对象数组
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
删除数组中的 last 元素并且不接受任何参数。您的意思可能是:
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
时将space放在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>
我有以下情况:
数组数量未定义。每个数组包含一些对象。这些对象中的每一个都有一个 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
删除数组中的 last 元素并且不接受任何参数。您的意思可能是:
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
时将space放在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>