Looping your current logic
My original answer below is, of course, performant as the proverbial January molasses even though I like the shape of it.
A little testing shows that just putting your current logic into a loop offers about the same or better performance than a generalized version RobbyCornelissen's answer (unless you unroll the loop in the reduce...) and has the benefit of simplicity. It relies on defining an array of column properties to iterate over.
const
data = [{ firstColumn: 1, secondColumn: 2 }, { firstColumn: 3, secondColumn: 4 }],
columns = ['firstColumn', 'secondColumn'],
result = [].concat(...columns.map(col => data.map((item) => item[col])));
console.log(result);
Generalized reduce()
const
data = [{ firstColumn: 1, secondColumn: 2 }, { firstColumn: 3, secondColumn: 4 }],
columns = ['firstColumn', 'secondColumn'],
result = data.reduce((a, item, i, { length }) => {
for (let j = 0; j < columns.length; j++) {
a[i + length * j] = item[columns[j]]
}
return a
}, []);
console.log(result);
Zip (original answer)
If the properties are guaranteed to be in order you could 'zip' the Object.values
. This will handle any number of properties without explicit desctructuring.
const data = [
{ firstColumn: 1, secondColumn: 2 },
{ firstColumn: 3, secondColumn: 4 }
];
const result = zip(...data.map(Object.values)).flat()
console.log(result)
<script>
/**
* @see https://stackoverflow.com/a/10284006/13762301
*/
const zip = (...rows) => [...rows[0]].map((_, c) => rows.map((row) => row[c]));
</script>
But to avoid relying on property order you can still destructure.
const result = zip(...data.map(({ firstColumn, secondColumn }) => [firstColumn, secondColumn])).flat()
see: Javascript equivalent of Python's zip function for more discussion on 'zip'.