将两个数组中的对象合并为一个

问题描述 投票:2回答:4

我有一个关于数组中合并对象的问题。最大的问题是如何在合并这些数组后保存这个数组结构,因为如果我在这些数组后使用.push()迭代我收到一个大数组。看看我的数据:

[ 
 [ 
   { name: '1' },
   { name: '2' },
   { name: '3' },
 ],
 [
   { name: '4' },
   { name: '5' },
   { name: '6' },
  ] 
]

[ 
 [ 
   { correct: false },
   { correct: true },
   { correct: false },
 ],
 [ 
   { correct: true },
   { correct: false },
   { correct: false },
 ] 
]

而我的观点是如何将这两个数组合并到一个数组中

[ 
 [ 
   { name: '1', correct: false },
   { name: '2', correct: true },
   { name: '3', correct: false },
 ],
 [ 
   { name: '4', correct: true },
   { name: '5', correct: false },
   { name: '6', correct: false },
 ] 
]

我尝试了循环,但我收到一个大数组,但我需要两个数组

for(i in nameArray) {
   for(j in nameArray[i]){
       var mergeObj = Object.assign(nameArray,correctArray[j]) //I get undefned
       correctArray.push(nameArray[i][j])
   }
}
javascript
4个回答
4
投票

你很近,但你有对象数组的数组,所以你需要correctArray[i][j]

const nameArray = [ 
 [{ name: '1' },{ name: '2' },{ name: '3' }],
 [{ name: '4' },{ name: '5' },{ name: '6' }] 
];

const correctArray = [ 
 [{ correct: false },{ correct: true },{ correct: false }],
 [{ correct: true },{ correct: false },{ correct: false }] 
];

nameArray.forEach((a, i) =>
  a.forEach((o, j) => Object.assign(o, correctArray[i][j]))
);

console.log(nameArray);

在这里我使用了.forEach(),这比在阵列上使用for-in更好。 nameArray中的对象正在变异,这就是你的结果。你可以使用.map()调用,并在Object.assign的开头添加一个空对象,如果你不想变异。

const nameArray = [ 
 [{ name: '1' },{ name: '2' },{ name: '3' }],
 [{ name: '4' },{ name: '5' },{ name: '6' }] 
];

const correctArray = [ 
 [{ correct: false },{ correct: true },{ correct: false }],
 [{ correct: true },{ correct: false },{ correct: false }] 
];

const result = nameArray.map((a, i) =>
  a.map((o, j) => Object.assign({}, o, correctArray[i][j]))
);

console.log(result);

2
投票

对于新的独立数组,您可以使用Array#reduce并在矩阵中构建新对象。

var array1 = [[{ name: '1' }, { name: '2' }, { name: '3' }], [{ name: '4' }, { name: '5' }, { name: '6' }]],
    array2 = [[{ correct: false }, { correct: true }, { correct: false }], [{ correct: true }, { correct: false }, { correct: false }]],
    result = [array1, array2].reduce((r, a) =>
        (a.forEach((b, i) =>
            (r[i] = r[i] || [], b.forEach((c, j) =>
                Object.assign(r[i][j] = r[i][j] || {}, c)))), r), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

1
投票

这是另一个版本,它有点夸张,并展示了如何在更复杂的数据集的情况下处理嵌套程度的示例。

const nameArray = [ 
 [ 
   { name: '1' },
   { name: '2' },
   { name: '3' },
 ],
 [
   { name: '4' },
   { name: '5' },
   { name: '6' },
  ] 
];

const correctArray = [ 
 [ 
   { correct: false },
   { correct: true },
   { correct: false },
 ],
 [ 
   { correct: true },
   { correct: false },
   { correct: false },
 ] 
];

var resultArray = []

function each(arr, fn){
    let len = arr.length, i = -1
    while(++i < len){ fn(arr[i], i) }
}

function addToArray(target, source){
    each(source, (elem, index) => {
        if(!target[index]){
            let newElem = elem.length ? [] : {}
            target[index] = newElem
        }
        if(elem.length){
            addToArray(target[index], elem)
        } else {
            let keys = Object.keys(elem)
            each(keys, key => {
                if(target[index][key]) console.warn(`Key ${key} already exists, overwriting`)
                target[index][key] = elem[key]
            })
        }
    })
}

addToArray(resultArray, nameArray)
addToArray(resultArray, correctArray)

console.log(JSON.stringify(resultArray, null, 2))

1
投票

我认为解决问题的最佳方法是递归函数。与此类似的东西:

var a = [ 
 [ 
   { name: '1' },
   { name: '2' },
   { name: '3' },
 ],
 [
   { name: '4' },
   { name: '5' },
   { name: '6' },
  ] 
]


var b = [ 
 [ 
   { correct: false },
   { correct: true },
   { correct: false },
 ],
 [ 
   { correct: true },
   { correct: false },
   { correct: false },
 ] 
]

var c = [
  [ 
    { hello: "world" }
  ]
];

function mergeRecursive(x,y){
  /**
   * Ignore functions
   */
  if( x instanceof Function ) {
    x = undefined;
  }
  if( y instanceof Function ) {
    y = undefined;
  }

  /**
   * Ignore undefineds
   */
   if( x == undefined ) {
     return y;
   }
   if( y == undefined ) {
     return x;
   }

   /**
    * Get the keys and remove duplicated
    */
   var kx = Object.keys(x).filter( (k) => ! ( x[k] instanceof Function ) );  
   var ky = Object.keys(y).filter( (k) => ! ( y[k] instanceof Function ) );
   var ks = kx.concat(
     ky.filter(
       (e) => kx.indexOf(e) == -1
     )
   );

   /**
    * Define the type of the result
    */
   var result;
   if (x instanceof Array && y instanceof Array ) {
     result = [];
     ks = ks.map( (k) => 1 * k ); // cast to number
   } else {
     result = {};
   }
   
   /**
    * Create the merge object recursively
    */
   ks.forEach( (k) => result[k] = mergeRecursive(x[k],y[k]) );
   return result;
}

var example1 = mergeRecursive(a,b);
console.log("example 1");
console.log(example1);

var example2 = mergeRecursive(example1,c);
console.log("example 2");
console.log(example2);
© www.soinside.com 2019 - 2024. All rights reserved.