そもそも何をしたいのか
言葉では説明しづらいので以下をご覧ください。
まず下記のコードを実行すると...
const createGrid = num => {
const serialNumArr = Array.from(new Array(num).keys());
return serialNumArr.map(v1 => serialNumArr.map(v2 => ++v2 + v1 * num));
};
const grid = createGrid(5);
以下のような5つの連番を値に持つ配列を5つ格納した配列、grid
が作成されます。
(画像1)
これの縦と横の中身を入れ替えて、以下のようにしたいとします。
(※そもそも配列に縦・横という概念は無いですが、見ため上こういった表現を使わせていただきます。)
どう実現するか
まず(画像2)の一個目の配列に注目すると、下記のように(画像1)の各配列の0番目の値が格納されている事が分かります。
[grid[0][0], grid[1][0], grid[2][0], grid[3][0], grid[4][0]]
同じ要領で二個目の配列には(画像1)の各配列の1番目の値が格納されています。
[grid[0][1], grid[1][1], grid[2][1], grid[3][1], grid[4][1]]
つまり最終的に作りたいものは以下のようなコードになります。
const swappedGrid = [
[grid[0][0], grid[1][0], grid[2][0], grid[3][0], grid[4][0]],
[grid[0][1], grid[1][1], grid[2][1], grid[3][1], grid[4][1]],
[grid[0][2], grid[1][2], grid[2][2], grid[3][2], grid[4][2]],
[grid[0][3], grid[1][3], grid[2][3], grid[3][3], grid[4][3]],
[grid[0][4], grid[1][4], grid[2][4], grid[3][4], grid[4][4]]
]
これをループで実現します。
実践編
まず大前提として、最終的にswappedGrid
はgrid
を元にした配列になるのでgrid
にmap
を使用します。
const swappedGrid = grid.map((row, i) => row)
そしてこのmap
内のrow
が、grid
が持つ各配列です。
更にswappedGrid
に格納される各値もこのrow
を元にした配列になるので、row
にもmap
を使用します。
const swappedGrid = grid.map((row, i) =>
row.map((_, ri) => _)
)
ただこれでは中身をそのまま返しているだけなので、row
の各値をどう実現するかにあるような形にしていきます。
やりたい事は「row
の各値にgrid
のn番目の配列
のm番目の値
を代入する」という処理なので、返り値はgrid[n][m]
となります。
const swappedGrid = grid.map((row, i) =>
row.map((_, ri) => grid[n][m])
);
そして最後にこのn
・m
にどのような値を使用すればよいかを考えます。
n
はgrid
が持つ各配列を参照するためもので、row
のループの中で0から1ずつ増えていき4で終わります。
grid
のlength
と、中身の各配列row
のlength
は常に一致するため、上記の中ではri
を使えば良いです。
次にm
はgrid
が持つ各配列内の値を参照するためのもので、row
のループの中で同じ値をとり、grid
のループの中では0から1ずつ増えていき4で終わります。
上記の中でそのような値はi
になります。
よって、最終的に以下のようなコードになります。
const swappedGrid = grid.map((row, i) =>
row.map((_, ri) => grid[ri][i])
);
・サンプル
https://jsfiddle.net/oLphu8am/
おわりに
いかがでしたでしょうか。
一見面倒臭そうな処理ですが、整理してみると意外と単純で、3行程度で実装できました。
頭の体操として楽しんでいただければ幸いです。