减去数组 - javascript [英] Subtract arrays - javascript

查看:55
本文介绍了减去数组 - javascript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有像这样的数组;

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并得到结果;

What I would like to do is subtract people2 from people and get result;

[mary, bob];

我如何实现这一目标?
TIA

How can I achieve this? TIA

推荐答案

你需要的第一件事是比较两个人的数学对等。我们不能使用 === 运算符,因为它测试两个对象的标识等价,而不是数学等价。例如:

The first thing you need is a way to compare two people for mathematical equivalence. We cannot use the === operator because it tests two objects for identity equivalence, not mathematical equivalence. For example:

var john = {name: "John Smith", age: 23};
var john2 = {name: "John Smith", age: 23};

console.log(john === john2); // false

因此我们创建了一个比较两个人的函数:

Hence we create a function to compare two people:

console.log(similarPeople(john, john2));

function similarPeople(a, b) {
    return a.name === b.name &&
           a.age === b.age;
}

该函数名称为 similarPeople 而不是 samePeople 是因为两个不同的人可能有相同的名字,可能年龄相同。

The reason the function is named similarPeople and not samePeople is because two different people may have the same name and may be of the same age.

两组A和B的差异被定义为A中所有那些不在B中的元素的集合。

The difference of two sets, A and B, is defined as the set of all those elements of A which are not in B.

最坏的情况是计算两组A和B的设定差异,大小 m n 分别将 O(m * n)时间。效率不高:

At worst computing the set difference of two sets, A and B, of sizes m and n respectively would take O(m * n) time. Not very efficient:

function difference(a, b, eq) {
    if (arguments.length < 3) eq = function (a, b) {
        return a === b;
    };

    var m = a.length;
    var n = b.length;

    var c = [];

    loop: for (var i = 0; i < m; i++) {
        var x = a[i];

        for (var j = 0; j < n; j++)
            if (eq(b[j], x))
                continue loop;

        c.push(x);
    }

    return c;
}

现在你可以得到两个人名单的区别如下:

Now you could get the difference of two lists of people as follows:

var people = [john, mary, bob];
var people2 = [john2];

console.log(difference(people, people2, similarPeople)); // [mary, bob]

参见演示: http://jsfiddle.net/F7RDs/

幸运的是,有一种更快的方法来计算大型集合的集合差异:指数。让我们创建一个函数来创建人员列表的索引:

Fortunately there's a faster way to compute the set difference for large sets: indices. Let's create a function to create an index of a list of people:

function indexFrom(people) {
    var length = people.length, index = {};

    for (var i = 0; i < length; i++) {
        var person = people[i];
        var name = person.name;

        if (index.hasOwnProperty(name)) var subindex = index[name];
        else var subindex = index[name] = {};
        subindex[person.age] = {};
    }

    return index;
}

现在我们为第二个人名单创建一个索引:

Now we create an index for the second list of people:

var index2 = indexFrom(people2);

我们还需要一个函数来测试一个人是否在使用其索引的列表中:

We also need a function to test whether a person is in a list using its index:

function hasPerson(person, index) {
    var name = person.name;

    return index.hasOwnProperty(name) &&
           index[name].hasOwnProperty(person.age);
}

最后我们可以创建一个更有效的差异实现如下:

Finally we can create a more efficient implementation of difference as follows:

function difference(a, index, has) {
    var m = a.length, c = [];

    for (var i = 0; i < m; i++) {
        var x = a[i];
        if (!has(x, index))
            c.push(x);
    }

    return c;
}

您可按如下方式使用它:

You use it as follows:

console.log(difference(people, index2, hasPerson)); // [mary, bob]

优点是创建索引需要 O(n)时间和计算差异需要 O(m)时间。因此总共只需要 O(m + n)时间而不是 O(m * n)时间。此外,您可以缓存索引以供将来使用。

The advantage is that creating an index takes O(n) time and calculating the difference takes O(m) time. Hence in total it only takes O(m + n) time instead of O(m * n) time. In addition you can cache the index for future use.

请参阅演示: http://jsfiddle.net/F7RDs/1/

希望这会有所帮助。

这篇关于减去数组 - javascript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆