假设我有一个由嵌套数组组成的“矩形网格”,如下所示:
let board = [
['a0', 'a1', 'a2', 'a3', 'a4'],
['b0', 'b1', 'b2', 'b3', 'b4'],
['c0', 'c1', 'c2', 'c3', 'c4'],
['d0', 'd1', 'd2', 'd3', 'd4'],
];
我正在尝试遍历其列中的 ,因此结果将类似于'a0', 'b0', 'c0', 'd0', 'a1'... etc
。
我当然可以使用旧的for循环来做到这一点:
const iterateAcrossColumnsES5 = () => {
for (let i = 0; i < board[0].length; i++) {
for (let j = 0; j < board.length; j++) {
console.log(board[j][i]);
}
}
}
但是我想尝试使其更简洁和可读性更好。我正在尝试在循环中使用 for .. of 和/或 for ..,但是我只能做到:
const iterateAcrossColumnsES6 = () => {
for (let [i, item] of Object.entries(board)) {
for(let row of board) {
console.log(row[i])
}
}
}
但是它既不是简洁也不是可读,并且仅在 board 是“正方形”(父数组)的情况下才有效长度与其子项相同),否则迭代次数过多或不足。
有可能做到吗?我没有尝试使用map()
或forEach()
,我很好。和他们在一起,但我很好奇我只能使用for..of
或for..in
。
答案 0 :(得分:4)
js中没有内置的功能,但是有了两个小的辅助函数,您可以用一种非常优雅的方式编写循环:
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
连接多个可迭代对象,以便您可以将它们作为一件事进行迭代,而zip
则采用数组数组并将其转置。
答案 1 :(得分:2)
您可以使用map
创建a0,b0....
的数组,然后进一步缩小它。然后使用带有定界符,
的join创建所需的结果
let board = [
['a0', 'a1', 'a2', 'a3', 'a4'],
['b0', 'b1', 'b2', 'b3', 'b4'],
['c0', 'c1', 'c2', 'c3', 'c4'],
['d0', 'd1', 'd2', 'd3', 'd4'],
];
var result = board.reduce((res, b) => res.map((elem, i) => elem + ',' + b[i])).join(',');
console.log(result);
答案 2 :(得分:2)
您可以更改面板的iterator,然后使用数组扩展或for...of
来获取项目:
const board = [
['a0', 'a1', 'a2', 'a3', 'a4'],
['b0', 'b1', 'b2', 'b3', 'b4'],
['c0', 'c1', 'c2', 'c3', 'c4'],
['d0', 'd1', 'd2', 'd3', 'd4'],
];
board[Symbol.iterator] = function() {
const rows = board.length;
const max = rows * board[0].length;
let current = 0;
return {
next: () => ({
value: this[current % rows][parseInt(current / rows)],
done: current++ === max
})
};
};
console.log([...board]);
for(const item of board) {
console.log(item);
}
答案 3 :(得分:1)
您可以转置矩阵然后进行迭代。
const transpose = (r, a) => a.map((v, i) => (r[i] || []).concat(v));
let board = [['a0', 'a1', 'a2', 'a3', 'a4'], ['b0', 'b1', 'b2', 'b3', 'b4'], ['c0', 'c1', 'c2', 'c3', 'c4'], ['d0', 'd1', 'd2', 'd3', 'd4']];
for (let a of board.reduce(transpose, [])) {
for (let v of a) {
console.log(v);
}
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 4 :(得分:1)
使用for...in
:
var board = [
['a0', 'a1', 'a2', 'a3', 'a4'],
['b0', 'b1', 'b2', 'b3', 'b4'],
['c0', 'c1', 'c2', 'c3', 'c4'],
['d0', 'd1', 'd2', 'd3', 'd4']
];
var result = [];
for (var i in board)
for (var j in board[i])
result[+j * board.length + +i] = board[i][j];
console.log(result);
不建议在数组上使用for...in
。 MDN Docs for reference
使用for...of
:
var board = [
['a0', 'a1', 'a2', 'a3', 'a4'],
['b0', 'b1', 'b2', 'b3', 'b4'],
['c0', 'c1', 'c2', 'c3', 'c4'],
['d0', 'd1', 'd2', 'd3', 'd4']
];
var result = [], i=0,j=0;
for (var arr of board) {
for (var val of arr)
result[j++ * board.length + i] = val;
i++;j=0;
}
console.log(result);
如果内部数组的长度不均匀,则数组中将出现空值。因此需要过滤这些。
答案 5 :(得分:0)
这只有在有方形板的情况下才有用。
let board = [
["a0", "a1", "a2", "a3", "a4"],
["b0", "b1", "b2", "b3", "b4"],
["c0", "c1", "c2", "c3", "c4"],
["d0", "d1", "d2", "d3", "d4"],
["e0", "e1", "e2", "e3", "e4"]
];
for (const i in board) {
for (const j in board) {
console.log(board[j][i]);
}
}