Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【JavaScript】碁盤の目状に並べた複数の配列の縦・横を入れ替える

そもそも何をしたいのか

言葉では説明しづらいので以下をご覧ください。

まず下記のコードを実行すると...

JavaScript
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)
Image from Gyazo
これの縦と横の中身を入れ替えて、以下のようにしたいとします。
(※そもそも配列に縦・横という概念は無いですが、見ため上こういった表現を使わせていただきます。)

(画像2)
Image from Gyazo

どう実現するか

まず(画像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]]

つまり最終的に作りたいものは以下のようなコードになります。

JavaScript
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]]
]

これをループで実現します。

実践編

まず大前提として、最終的にswappedGridgridを元にした配列になるのでgridmapを使用します。

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の各値にgridn番目の配列m番目の値を代入する」という処理なので、返り値はgrid[n][m]となります。

const swappedGrid = grid.map((row, i) =>
  row.map((_, ri) => grid[n][m])
);

そして最後にこのnmにどのような値を使用すればよいかを考えます。

ngridが持つ各配列を参照するためもので、rowのループの中で0から1ずつ増えていき4で終わります。
gridlengthと、中身の各配列rowlengthは常に一致するため、上記の中ではriを使えば良いです。

次にmgridが持つ各配列内の値を参照するためのもので、rowのループの中で同じ値をとり、gridのループの中では0から1ずつ増えていき4で終わります。
上記の中でそのような値はiになります。

よって、最終的に以下のようなコードになります。

const swappedGrid = grid.map((row, i) =>
  row.map((_, ri) => grid[ri][i])
);

・サンプル
https://jsfiddle.net/oLphu8am/

おわりに

いかがでしたでしょうか。
一見面倒臭そうな処理ですが、整理してみると意外と単純で、3行程度で実装できました。

頭の体操として楽しんでいただければ幸いです。

taku-hu
普段はReact・Vueあたりを書いてるフロントエンドエンジニア。 好きな言語はTypeScript。
https://taku-hu.web.app/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away