使用JavaScript合并数组的数组

3
我是一名 JavaScript 初学者,正在尝试合并两个数组。
我有两个像这样的数组:
 arr1[
{
        description : "this is a object",
        array       : ["a","b"]
 }
    ]

 arr2[
{
       array : ["c","d"]
} 
   ]

我希望您能够得到一个像这样的结果javascript对象
result = { description : "this is a object", array : ["a","b","c","d"]}

元素的顺序对我来说不重要。所以我尝试了以下内容。

result = $.extend(true, {},arr1,arr2)[0];

但是这会返回以下输出。
result = { description : "this is a object", array : ["c","d"] }

这不是我想要的结果,因为它缺少值。我该如何按照自己的方式合并它们?

2个回答

4
你混淆了数组和哈希表。在你的“数组”中出现的冒号分隔符表明你试图定义哈希表。哈希表必须用花括号 {} 而不是方括号 [] 进行界定。
假设你想定义并组合两个哈希表,下面是如何在没有任何泛化的情况下完成它,即通过明确指定如何将来自每个输入哈希表的每个键/值对合并到组合哈希表中:

var obj1 = {
    description : "this is an object",
    array       : ["a","b"]
};

var obj2 = {
    array : ["c","d"]
};

var res = {
    description : obj1.description,
    array       : obj1.array.concat(obj2.array)
};

alert(res.description); // "this is an object"
alert(res.array); // a,b,c,d

现在,对于更一般的解决方案,您可以编写处理各种数据类型及其在输入哈希对中碰撞的“标准”逻辑:

var obj1 = {
    description : "this is an object",
    array       : ["a","b"]
};

var obj2 = {
    array : ["c","d"]
};

function combine(obj1,obj2) {
    var res = {};
    for (var k1 in obj1) {
        if (!obj1.hasOwnProperty(k1)) continue;
        if (obj2.hasOwnProperty(k1)) { // collision
            if (typeof(obj1[k1]) !== typeof(obj2[k1])) throw "type mismatch under key \""+k1+"\".";
            if (Array.isArray(obj1[k1])) {
                res[k1] = obj1[k1].concat(obj2[k1]);
            } else if (typeof(obj1[k1]) === 'string' || obj1[k1] instanceof String) {
                res[k1] = obj1[k1]+obj2[k1];
            } else if (typeof(obj1[k1]) === 'object') {
                res[k1] = combine(obj1[k1],obj2[k1]);
            } else {
                throw "unsupported collision type "+typeof(obj1[k1])+" under key \""+k1+"\".";
            }
        } else {
            res[k1] = obj1[k1];
        }
    }
    for (var k2 in obj2) {
        if (!obj2.hasOwnProperty(k2)) continue;
        if (obj1.hasOwnProperty(k1)) continue; // already handled it above
        res[k2] = obj2[k2];
    }
    return res;
}

var res = combine(obj1,obj2);

alert(res.description); // "this is an object"
alert(res.array); // a,b,c,d


在您进行编辑后,我的解决方案仍然适用;您只需要先对数组进行索引以提取包含的对象。以下是修改后的实现:

解决方案1:

var res = {
    description : arr1[0].description,
    array       : arr1[0].array.concat(arr2[0].array)
};

解决方法2:
var res = combine(arr1[0],arr2[0]);

谢谢您的纠正。让我来更正一下。它基本上是一个数组中的对象。我正在处理类似于这样的东西 arr1[ { description : "this is a object", array : ["a","b"] } ] 同时,数组:["a", "b"]会动态添加,所以当我尝试将其引用为arr1 [0] .array时,它会给我错误。请帮忙。 - qualitytest
@qualitytest 请看我的修改。关于array哈希表项的动态性,那是一个独立的问题。目前,上述代码在您页面的上下文中运行,无论array条目是否存在于哈希表中,都取决于您页面的更大设计。如果该条目存在,则arr1[0].array不会失败。如果不存在,则我的第一个解决方案将失败,因为它明确引用了arr1[0].array,但我的第二个解决方案不会失败,因为它仅使用输入哈希表中现有的条目。 - bgoldst
但我刚刚注意到,嵌套数组中显示了重复的元素。 :( 请帮忙 - qualitytest
Array.prototype.concat() 函数不会删除重复项。如果您想这样做,您必须添加代码。我不知道在 JavaScript 中从数组中删除重复项的任何简单内置方法;请参见 https://dev59.com/iWox5IYBdhLWcg3waziQ 以获取一些选项。 - bgoldst
我使用了这个 https://dev59.com/BHI-5IYBdhLWcg3w-9wK 并且它很有帮助。再次感谢! :) - qualitytest

0

也许你应该看一下这个递归合并函数的实现。

它应该具有与PHP array_merge_recursive相同的行为。

代码:

function array_merge_recursive(arr1, arr2) {
  //  discuss at: http://phpjs.org/functions/array_merge_recursive/
  // original by: Subhasis Deb
  //    input by: Brett Zamir (http://brett-zamir.me)
  // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  //  depends on: array_merge
  //   example 1: arr1 = {'color': {'favourite': 'read'}, 0: 5}
  //   example 1: arr2 = {0: 10, 'color': {'favorite': 'green', 0: 'blue'}}
  //   example 1: array_merge_recursive(arr1, arr2)
  //   returns 1: {'color': {'favorite': {0: 'red', 1: 'green'}, 0: 'blue'}, 1: 5, 1: 10}

  var idx = '';

  if (arr1 && Object.prototype.toString.call(arr1) === '[object Array]' &&
    arr2 && Object.prototype.toString.call(arr2) === '[object Array]') {
    for (idx in arr2) {
      arr1.push(arr2[idx]);
    }
  } else if ((arr1 && (arr1 instanceof Object)) && (arr2 && (arr2 instanceof Object))) {
    for (idx in arr2) {
      if (idx in arr1) {
        if (typeof arr1[idx] === 'object' && typeof arr2 === 'object') {
          arr1[idx] = this.array_merge(arr1[idx], arr2[idx]);
        } else {
          arr1[idx] = arr2[idx];
        }
      } else {
        arr1[idx] = arr2[idx];
      }
    }
  }

  return arr1;
}

尽管我喜欢这个想法,但链接的代码将覆盖arr1的成员。原始的PHP函数不会这样做。相反,它只会返回合并的数组。这个移植的函数根本不需要返回语句,因为在运行此函数之后,返回值与第一个参数具有相同的内容。 - GottZ
此外,您还需要使用array_merge。不仅如此.. array_merge_recursive和array_merge必须是同一对象的成员。我猜您需要像这样做:var phpjs = {}; phpjs.prototype = {array_merge:array_merge, array_merge_recursive:array_merge_recursive}; 这将导致函数调用,例如:var mergedArray = phpjs.array_merge_recursive(arr1, arr2); - GottZ
也许你在2022年寻找的是这样的东西:function merge(a, b) { var r = {}; Object.keys(a).forEach((x) => { r[x] = a[x]; }); Object.keys(b).forEach((x) => { r[x] = b[x]; }); return r; } - mxl
甚至更简单的是,您可以使用 Object.assign(a, b) - mxl

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