1

I'm trying to write a function that takes an array of objects, and an unlimited number of arrays, and combines them to form a single object. The inputs would follow this pattern:

let x = [{ name: 'Tom' }, { name: 'John' }, { name: 'Harry' }]; let y = [[1, 2, 3], 'id']; let z = [['a', 'b', 'c'], 'value']; combine(x, y, z); 

With the second element of y and z acting as the object key. Using these arguments, the function should return the following array:

[ { name: 'Tom', id: 1, value: 'a' }, { name: 'John', id: 2, value: 'b' }, { name: 'Harry', id: 3, value: 'c' }, ] 

The index of the current object should be used to get the correct element in the array. I have made an attempt at the problem:

function combine(object, ...arrays) { return object.map((obj, index) => { let items = arrays.map(arr => ({ [arr[1]]: arr[0][index] })); return Object.assign({}, obj, { items }); }); } 

This almost does the job, but results in the array items being hidden inside a nested items array, How can I solve this?

1
  • Use map check Demo Commented Sep 16, 2015 at 7:26

3 Answers 3

3

You had been assigning an object of object, and the result was a new object with the element items inside (another feature of object literal).

This approach use reduce instead of map and direct assign instead of object literal.

function combine(object, ...arrays) { return object.map((obj, index) => { const items = arrays.reduce((acc, arr) => { acc[arr[1]] = arr[0][index] ; return acc; }, {}); return Object.assign({}, obj, items); }); } const x = [{ name: 'Tom' }, { name: 'John' }, { name: 'Harry' }]; const y = [[1, 2, 3], 'id']; const z = [['a', 'b', 'c'], 'value']; combine(x, y, z); 

You can also use the spread operator in the Object.assign, like this:

function combine(object, ...arrays) { return object.map((obj, index) => { let items = arrays.map(arr => ({ [arr[1]]: arr[0][index] })); return Object.assign({}, obj, ...items); }); } 
Sign up to request clarification or add additional context in comments.

Comments

1

This almost does the job, but results in the array items being hidden inside a nested items array

The problem is that items is an array, whereas you only need the current item inside of that particular map callback. No need to nest loops here.

Also I would recommend avoiding multiple properties per combine call. The resulting code would look like this:

function combine(objects, [values, key]) { return objects.map((o, i) => Object.assign({[key]: values[i]}, o) ); } combine(combine(x, y), z); 

If you then have multiple extensions to do, you can also use

[y, z].reduce(combine, x) 

Comments

0

With map and computed keys, you can achieve this. Here's a working example:

let x = [{ name: 'Tom' }, { name: 'John' }, { name: 'Harry' }]; let y = [[1, 2, 3], 'id']; let z = [['a', 'b', 'c'], 'value']; let result = []; x.map(function (el, index) { result.push(el); let index = result.length -1; result[index][y[1]] = y[0][index]; result[index][z[1]] = z[0][index]; }); console.log(result); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.