减去数组 - JavaScript

9

我有如下数组:

var john = { name: "John Smith", age: 23 };
var mary = { name: "Mary Key", age: 18 };
var bob = { name: "Bob-small", age: 6 };
var people = [john, mary, bob];

var john2 = { name: "John Smith", age: 23 };
var people2 = [john2];

我想要做的是将people2从people中减去并得到结果。
[mary, bob];

我该如何实现这个?谢谢!

1
.filter() - Andreas
3
阅读 What is the fastest or most elegant way to compute a set difference using Javascript arrays?。这篇文章讨论了如何使用JavaScript数组计算集合差异的最快或最优雅的方法。其中一些解决方案包括使用filter()、reduce()和ES6 Set等功能。建议根据具体情况选择最适合您需求的方法,以获得最佳性能和可读性。 - Grijesh Chauhan
3个回答

8

两个集合 A 和 B 的差集是指 A 集合中所有不在 B 集合中的元素组成的集合。如果我们采用朴素的方法来实现它,计算两个大小分别为 mn 的集合的差集需要 O(m * n) 的时间。这样效率不高:

const john1 = { name: "John Smith", age: 23 };
const john2 = { name: "John Smith", age: 23 };
const mary = { name: "Mary Key", age: 18 };
const bob = { name: "Bob-small", age: 6 };

const people1 = [john1, mary, bob];
const people2 = [john2];

const eqPerson = (p, q) => p.name === q.name && p.age === q.age;

const result = people1.filter(p => people2.every(q => !eqPerson(p, q)));

console.log(result); // [mary, bob]


幸运的是,使用哈希算法可以更快地计算大型数据集的差异。

const john1 = { name: "John Smith", age: 23 };
const john2 = { name: "John Smith", age: 23 };
const mary = { name: "Mary Key", age: 18 };
const bob = { name: "Bob-small", age: 6 };

const people1 = [john1, mary, bob];
const people2 = [john2];

const hashPerson = ({ name, age }) => `${name} ${age}`;

const hashSet = new Set(people2.map(hashPerson));

const result = people1.filter(p => !hashSet.has(hashPerson(p)));

console.log(result); // [mary, bob]

优点在于创建哈希集合需要 O(n) 的时间,计算差异需要 O(m) 的时间。因此总共只需要 O(m + n) 的时间,而不是O(m * n) 时间。此外,您可以在将来重复使用哈希集合。

很好的解释。是的,我不理解arguments.lengtharguments是从哪里来的?也许这是一个非常愚蠢的问题,但我对Web技术还比较新。您能告诉我hasOwnProperty是什么意思吗? - Grijesh Chauhan
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments - Aadit M Shah

5

这里有一个简单的解决方案:

var diff = people.filter(function(item) {
  return !people2.some(function(test){
    return test.name === item.name && test.age === item.age;
  });
});

请确保传递给people2.some函数的功能正确检查两个对象是否相等,因为==将失败,因为您具有具有相同属性的不同对象的引用。


0
所以,这里是最终运行的代码。复制、粘贴并检查输出。首先,它将字符串分开(以逗号分隔)。然后逐个进行比较。请点击此链接查看:http://jsfiddle.net/DXRZ4/
<html>
  <head>
    <script>
        var a = new Array(); var i=1; var people = new Array();
        function fun() {
            var str = "john,john,bob",
                l = str.split(",");
            for(i=0; i<3; i++) {
                a[i] = l[i];
                // this will show the comma separated strings
                document.writeln(l[i]);
            }
            for(i=0; i<3; i++) {
                t=a[i]; 
                j=a[i+1];
                if((a[i]==a[i+1]) || (a[i]==a[i+2])) {
                    // it will store the position of string which are same
                    p=i; 
                }
            }
            for(i=0; i<3; i++) { 
                if(p!=i){
                    document.writeln("Subtracted Strings are:-");
                    document.writeln(l[i]);
                }
            }
        }
    </script>
  <body>
    <input type="button" name="b1" onClick="fun()">
  </body>
</html>

1
为什么不为读者创建一个fiddle,而不是期望他们复制/粘贴你的代码呢? - Aadit M Shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接