简体   繁体   English

在Javascript中,如何合并对象数组?

[英]In Javascript, how to merge array of objects?

var array1 = [{ "name" : "foo" , "age" : "22"}, { "name" : "bar" , "age" : "33"}];
var array2 = [{ "name" : "foo" , "age" : "22"}, { "name" : "buz" , "age" : "35"}];

What's the fastest way to have (no duplicates, name is the identifier): 什么是最快的方式(没有重复,名称是标识符):

[{ "name" : "foo" , "age" : "22"}, { "name" : "bar" , "age" : "33"}, { "name" : "buz" , "age" : "35"}];

With and without jquery if possible. 有和没有jquery如果可能的话。

Here's a general purpose function that would merge an arbitrary number of arrays, preventing duplicates of the passed in key. 这是一个通用函数,它将合并任意数量的数组,防止传入密钥的重复。

As it is merging, it creates a temporary index of the names used so far and only merges new elements that have a unique name. 在合并时,它会创建到目前为止使用的名称的临时索引,并且只合并具有唯一名称的新元素。 This temporary index should be much faster than a linear search through the results, particularly as the arrays get large. 这个临时索引应该比通过结果的线性搜索快得多,特别是当数组变大时。 As a feature this scheme, it filters all duplicates, even duplicates that might be in one of the source arrays. 作为此方案的一项功能,它可以过滤所有重复项,甚至是可能位于其中一个源阵列中的重复项。

If an element does not have the keyName, it is skipped (though that logic could be reversed if you want depending upon what error handling you want for that): 如果一个元素没有keyName,则跳过它(虽然如果你想要的话,可以反转这个逻辑,取决于你想要的错误处理):

var array1 = [{ "name" : "foo" , "age" : "22"}, { "name" : "bar" , "age" : "33"}];
var array2 = [{ "name" : "foo" , "age" : "22"}, { "name" : "buz" , "age" : "35"}];

function mergeArrays(keyName /* pass arrays as additional arguments */) {
    var index = {}, i, len, merge = [], arr, name;

    for (var j = 1; j < arguments.length; j++) {
        arr = arguments[j];
        for (i = 0, len = arr.length; i < len; i++) {
            name = arr[i][keyName];
            if ((typeof name != "undefined") && !(name in index)) {
                index[name] = true;
                merge.push(arr[i]);
            }
        }
    }
    return(merge);
}

var merged = mergeArrays("name", array1, array2);

// Returns:
// [{"name":"foo","age":"22"},{"name":"bar","age":"33"},{"name":"buz","age":"35"}]

You can see it work here: http://jsfiddle.net/jfriend00/8WfFW/ 你可以在这里看到它的工作: http//jsfiddle.net/jfriend00/8WfFW/

When this algorithm is run against the Matt algorithm in jsperf using larger arrays, this algorithm is around 20x faster: 当使用更大的数组对jsperf中的Matt算法运行此算法时,此算法的速度提高约20倍:

在此输入图像描述

What you have are completely different objects, and there is nothing built into JavaScript to detect identical objects; 你拥有的是完全不同的对象,JavaScript中没有内置任何东西来检测相同的对象; ie objects which have the same attributes, so we have to write our own function: 即具有相同属性的对象,因此我们必须编写自己的函数:

function merge(set1, set2) {
    // Already put the elements of set1 in the result array
    // see Array.slice
    var result = set1.slice(0);

    // Utility function which iterates over the elements in result
    // and returns true if an element with the same name already
    // exists. false otherwise
    function exists(obj) {
        for (var i=0;i<result.length;i++) {
            if (result[i].name == obj.name) {
                return true;
            }
        }

        return false;
    }

    // Now simply iterate over the second set and add elements
    // which aren't there already using our exists() function.
    for (var i=0;i<set2.length;i++) {
        if (!exists(set2[i])) {
            result.push(set2[i]);
        }
    }

    return result;
}

You'd then call it with; 然后你打电话给它;

var result = merge(array1, array2);

To become more confident with object equality try the following experiment; 为了对对象平等更有信心,请尝试以下实验;

var a = { "test": 1 };
var b = { "test": 1 };
var aClone = a;

alert(a == a); // true
alert(a == b); // false
alert(a == aClone); // true

I don't think that plain javascript offers anything better than iterating the array's and manually implementing the logic for that. 我不认为普通的javascript提供的东西比迭代数组和手动实现逻辑更好。 What I would advice is to use the awesome underscore.js library that provides many functional-like facilities to handle arrays and collections in general; 我建议使用令人敬畏的underscore.js库,它提供了许多类似功能的工具来处理数组和集合。 to solve your problem for example this could work: 以解决您的问题为例,这可能有效:

http://documentcloud.github.com/underscore/#union http://documentcloud.github.com/underscore/#union

jQuery is another option, but it is more a DOM-manipulation browser-oriented library, while underscore is made to deal with these kind of problems. jQuery是另一种选择,但它更像是面向浏览器的DOM操作库,而下划线是为了解决这些问题。

The first way I can think of: 我能想到的第一种方式:

array3 = [];
for(object in array1) {
    var match=false;
    for(already in array3) {
        if (already==object) {
            match=true;
            break; } }
    if (match) array3.push(object); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM