【问题标题】:Filter multiple arrays of objects过滤多个对象数组
【发布时间】:2015-03-06 15:44:25
【问题描述】:

我有以下情况:

有未定义数量的数组。每个数组包含一些对象。这些对象中的每一个都有一个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'}]}

【问题讨论】:

  • 你能把这个放在小提琴里吗?
  • 如何定义“重复”?相同的id 还是相同的所有属性?
  • 你想如何过滤掉重复项,是什么给了总统:第一次出现的 id 比最后一次更重要吗?是否依赖于name的值?

标签: javascript arrays filter


【解决方案1】:

主要问题在这里:

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 时,为什么要在id 前面加上空格? 机会你有 id 值,其名称存在于对象上,例如 toStringvalueOf。 (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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多