1

I have 2 arrays

array1 = ["a","b"]
array2 = [ ["1","2","3"],["10","11","12"]]

The output I want is an array of objects

[
 {array1: a , array2: 1},
 {array1: a , array2: 2},
 {array1: a , array2: 3},

 {array1: b , array2: 10},
 {array1: b , array2: 11},
 {array1: b , array2: 12},
]

Is there a concise way to achieve this output instead of nested loops

3
  • can you encapsulate some of the logic in a function? Doesn't change complexity but could enhance readability. Commented Feb 7, 2019 at 20:16
  • eh, probably, but most good solutions will include some form of a nested loop. Commented Feb 7, 2019 at 20:22
  • Nothing wrong with nested loops for nested data… Commented Feb 7, 2019 at 20:43

5 Answers 5

2

It seems like you just need two loops. There are many ways to do that. A concise way is to reduce array1 and map array2 into the result within the outer loop:

let array1 = ["a","b"]
let array2 = [ ["1","2","3"],["10","11","12"]]

let res = array1.reduce((arr, array1, i) => 
  arr.concat(array2[i].map(array2 => ({array1, array2})))
, [])

console.log(res)

Sign up to request clarification or add additional context in comments.

Comments

1

You could reduce the arrays and get the cartesian product of the outer elements of each arrays.

function getCartesian(object) {
    return Object.entries(object).reduce((r, [k, v]) => {
        var temp = [];
        r.forEach(s =>
            (Array.isArray(v) ? v : [v]).forEach(w =>
                (w && typeof w === 'object' ? getCartesian(w) : [w]).forEach(x =>
                    temp.push(Object.assign({}, s, { [k]: x }))
                )
            )
        );
        return temp;
    }, [{}]);
}

var array1 = ["a", "b"],
    array2 = [["1", "2", "3"], ["10", "11", "12"]],
    result = array1.reduce((r, a, i) =>
        r.concat(getCartesian({ array1: a, array2: array2[i] })), [])

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

1 Comment

Thanks, But your solution gives a full Cartesian Product, I dont need that, if you see my question , i just need 6 objects in the result, while your solutions gives me 2x6 = 12, I need "a" with "1","2" and "3" whereas "b" with "10","11" and "12"
0

You can just use the map() method on the second array then use another map() method on the nested arrays. Finally, use the indexes to group the "nth" element from the first array with the elements from the "nth" nested array together inside an object like this:

array1 = ["a","b"]
array2 = [ ["1","2","3"],["10","11","12"]]
let x = [];

array2.map((e,i) => { // call function on every element in array2 with index callback
  e.map((f,j) => { // call function on every element in the nested arrays with index callback
    let obj = {};
    obj["array1"] = array1[i];
    obj["array2"] = f;
    x.push(obj);
  });
});

console.log(x);

Comments

0

This is a similar approach to Marks Meyer answer, but using a forEach() instead of the reduce().

let array1 = ["a","b", "c"];
let array2 = [["1","2","3"], ["10","11","12"]];
let res = [];

array1.forEach((x, i) =>
{
    if (array2[i])
        res.push(...array2[i].map(y => ({array1: x, array2: y})));
});

console.log(res);

Comments

0

You can use .map() and .flat() to map each element of array2 for each element of array1 then flatten the resulting array.

const array1 = ["a","b"]
const array2 = [ ["1","2","3"],["10","11","12"]]

let res = array1.map((array1, i) => array2[i].map(array2 => ({array1, array2}))).flat()

console.log(res)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.