0

I have object with array of options. On each option I need to create flat object. Like so

name: 'win10',
        architectures: ['x64', 'x86'],
        languages: ['en', 'ru'],

Transforms into:

[
{ name: 'win10',
        architectures 'x64',
        languages: 'en',
}, {
name: 'win10',
        architectures:  'x86',
        languages: 'ru',
}, {
name: 'win10',
        architectures: 'x64',
        languages: 'en',
}, {
name: 'win10',
        architectures: 'x86',
        languages: 'ru',
}
]

2 Answers2

1

This should do:


let input = {
        name: 'win10',
        architectures: ['x64', 'x86'],
        languages: ['en', 'ru']
};

function flatten(system) {
        let output = [];

        for (let i = 0; i < system.architectures.length; i++) {
                const arch = system.architectures[i];
                for (let j = 0; j < system.languages.length; j++) {
                        const lang = system.languages[j];
                        output = [...output, {
                                name: system.name,
                                architectures: arch,
                                language: lang
                        }];
                }
        }
        return output;
}

const output = flatten(input);

console.log(output);

  • Is there any reason to create a new array in every loop with `output = [...output, {..}]` instead of simply doing `output.push()`? – adiga Apr 27 '21 at 11:21
  • Both approaches are valid, `output = [...output, {..}]` unpacks the output array and appends the object to it. You can choose `.push()` if you prefer it –  Apr 27 '21 at 11:26
  • But a new array is being created in every iteration and another array is being spread for no reason. It makes sense doing something like react where mutating the array isn't allowed. If it is being assigned back to the `ouptut` variable, this is completely pointless – adiga Apr 27 '21 at 11:26
  • As I've said, you can choose any of them. It's up to you :) –  Apr 27 '21 at 11:29
1

This is another approach

var x = { name: 'win10',
        architectures: ['x64', 'x86'],
        languages: ['en', 'ru'] }
var k = [];
 x.architectures.forEach(p => {
 x.languages.forEach((y => {
    k.push({name: x.name, architectures:p,languages:y})
  }))
})

console.log(k)
Tony Tom
  • 1,435
  • 1
  • 10
  • 17
  • This is almost the same as my approach but you must note that `forEach` is waaaay slower than `for() {...}` –  Apr 27 '21 at 11:28
  • It depends on the array size, always go with the latest syntax – Tony Tom Apr 27 '21 at 11:38
  • It's not as important in this example but when going for performance, you should keep that in mind, the speedup is 150-200% (from my tests) –  Apr 27 '21 at 11:40
  • I agree for loop is much faster than forEach but syntax wise forEach is cleaner more readability and chances of accidental errors are less If you are interested to know more about forEach and for you can check this doc https://alligator.io/js/foreach-vs-for-loops/ – Tony Tom Apr 27 '21 at 11:43
  • 1
    And I agree forEach is quite a bit cleaner. Thanks for the great document on the differences! –  Apr 27 '21 at 11:46