Let's say I have a "rectangular grid" made of nested arrays, like this:
let board = [
['a0', 'a1', 'a2', 'a3', 'a4'],
['b0', 'b1', 'b2', 'b3', 'b4'],
['c0', 'c1', 'c2', 'c3', 'c4'],
['d0', 'd1', 'd2', 'd3', 'd4'],
];
I am trying to iterate across its columns, so the result will be like 'a0', 'b0', 'c0', 'd0', 'a1'... etc
.
Of course I can do it using good old for loop:
const iterateAcrossColumnsES5 = () => {
for (let i = 0; i < board[0].length; i++) {
for (let j = 0; j < board.length; j++) {
console.log(board[j][i]);
}
}
}
But I like to try make it more ES6 like terse and readable. I am trying to use for.. of and/or for.. in loops, but I got only as far as:
const iterateAcrossColumnsES6 = () => {
for (let [i, item] of Object.entries(board)) {
for(let row of board) {
console.log(row[i])
}
}
}
But it is nor terse nor readable, and it kinda works only in case that board is a 'square' (the parent array length is the same as its childrens), otherwise I got either too much or not enough iterations.
It is possible to do it? I haven't try to use map()
or forEach()
, I'm O.K. with them, but I am curious if I can use only for..of
or for..in
.
Nothing built-in for that in js, but with two tiny helper functions you can write the loop in a quite elegant way:
function *chain(its) {
for (let it of its)
yield *it
}
function zip(arrays) {
return arrays[0].map((e, i) => arrays.map(a => a[i]))
}
//
let board = [
['a0', 'a1', 'a2', 'a3', 'a4'],
['b0', 'b1', 'b2', 'b3', 'b4'],
['c0', 'c1', 'c2', 'c3', 'c4'],
['d0', 'd1', 'd2', 'd3', 'd4'],
]
console.log([...chain(board)].join(' '))
console.log([...chain(zip(board))].join(' '))
chain
connects multiple iterable objects so that you can iterate them as one thing and zip
takes an array of arrays and transposes it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With