人文出身の私が、やっとfor文と配列と仲良くなった話

## なぜこの記事書いたの？

文系の中での人文出身の私は数字、数学が大の苦手です。そんな中、コードを書き始めて半年、実は最近までJavaScriptの`for文`と`配列`があまりよく分からず、なんとなく書いていました。

そのため、同じく数学、数字、計算苦手の方向けに、私なりの理解を共有したいと思います。

前提：理解できたら楽しくなるよ!! (重要)

## こういう人に向けて書いてます

* 複数の配列が出てくる時に、データを取得するのに悩む方
* JavaScriptが好きだけど、得意ではない方
* 配列と仲良くなりたい方

に向けて書いております。

## やりたいことから話します

今回やることはGoogleフォームから取れたデータをスプレッドシートで保存し、そして、スプレッドシートからデータを取得する。そして、取得したデータを処理し、Laravel経由でChart.jsで表示させる。

スプレッドシートのデータをGoogleSheetAPI経由でLaravelで表示させる話は下記の記事をご覧ください ^^

https://qiita.com/guolam/items/ccb1e68224584807cb4b

今回紹介するのが、**データを取得した後**の課題です。

前回実現できたのが、取得したデータをChart.jsで表示させること。
うん、確かにチャートができた瞬間は嬉しい!!!

そして、作ってから気づきました。

ツールの性質により、２回のアンケート結果を重なって表示し、ユーザーの変化を可視化したいので、Chart.jsのサンプルコードのように、複数のLabelを表示させるのが目標です。

作りたいイメージはこれです：
![スクリーンショット 2023-06-14 23.46.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959760/43f59ee8-b139-899a-ac9f-70d77a52e1c4.png)


つまり、`data`の部分が同じメルアドで入力した人が、違う時間で入力したアンケートを、同じレダーチャートで表示させること。

## 何か難しかったこと　＆　その解決案

データの形式はスプレッドシートで一覧となって、コントローラ経由で、メールアドレスをキーにして照合、その人だけのデータを抽出することができた。

例えば、その人が3回回答したら、検証画面から取得したデータを見ると、このように：

![スクリーンショット 2023-06-18 10.38.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959760/fcfcda90-c3de-e7c2-b3cb-8bb01a1d1c8c.png)

dataの中に、複数の配列が入っています。
console.log(data)を入れると、検証画面から上記の値が出てきました。

アイドルに例えて、わかりやすく解説してくれた文章もありました。

http://ysklog.net/java/5-18.html

ここから欲しいデータを抽出するに必要なやり方と考え方をずるずる書いていきます。
今回話したいのが、複数のデータを取得してからの処理です。

## 取得したデータをどう調理するか？
### 1. 一つずつ取得する方法

data内の二つの配列が入ってるのがわかりました。
一つだけ取得するには、このように：

`data[0][2]`

これが、dataの0列目の2番目(="当てはまる")です

そこまでは教科書通りだし、理解（￣+ー￣）


### 2. 空の配列にデータを追加 (PUSH!!!)

さて、これから増えてくるこの配列の連続に、さらに`data[0]の2番目から5番目まで`を取ってきたい。どうすればいいんだ？

って時に、空の配列を作成してから内容を追加していく手法があります。

```
const answers=[];
```

↑空の配列です。
この空の配列に欲しいデータを切り取って、入れる。

データを切り取る関数sliceを使う。
`slice`は切り取る時に使う関数です。

このように、sliceを使って、
データの0番目の2-5番目を取得できました。

```
    const samples=[];
  //dataの一部を切り取って、answerの配列に入れる(pushする)

  if (data[0]) {
     const answer = data[0].slice(2, 6);
     answer.push(samples);
      }
```

pushしたら、空の配列 (samples)に入れられますので、そこにconsole.log(samples)をかけると、認証画面からこれらを確認できます。

![スクリーンショット 2023-06-18 22.22.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959760/646f670a-80ea-59ee-0f7e-7e7a13bb4615.png)

そして、2-5番を取得するけど、`data[0].slice(2, 6)`で書く理由としては、`6`は切り離された部分なので、実際2-5しかカウントされないそうです。

### 3. for 文を使って、複数の配列を処理する

sliceを使って、指定する配列から値を取れたが、
じゃ、どうやったら二次元配列の中の値を取得できるの？

答えはfor文。
for文を使って、**繰り返し処理**すれば(回せば)、
それぞれの値を取得することができます。

実際の構文はそんなに複雑ではない。

```
for (let i = 0; i < 5; i++) 
```
iが5になるまで、ずっと繰り返して処理するよ！という意味です。
それをさっきの文に合わせたら、

```
const samples =[];
for (let i = 0; i < 5; i++) {

  //dataの一部を切り取って、answerの配列に入れる(pushする)

  if (data[i]) {
     const samples = data[i].slice(2, 6);
     answer.push(samples);
      }
```
切り取れたら、このように：
![スクリーンショット 2023-06-18 22.29.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959760/a1deea29-d2c7-434f-be88-39e6db0fed38.png)
for分を使って、回していくので、dataの中にある配列を一列ずつ繰り返して処理する。
それぞれの配列の中に2-5番目のデータを取得していくイメージです。

ここで複数の値を取得できたので、あとは意外と簡単でした。
for分があれば、自由に欲しい値を取得できることがわかったので、
そこからの計算は案外簡単でした。

### 4. ちょっとおさらい
配列の処理は大体このパターンでなんとかできます!! 
配列が苦手の私が考える順番はこちら：(初心者🔰なりに)

1. 全体の値を取得する
2. 全体から欲しい値の取得方法を考える。今回だとsliceを使って、欲しい値の範囲を切り取った
3. 取得した値を空の配列を使って、配置する
4. for文を使って、単体の調理を繰り返し処理することによって、二次元配列から欲しい値を取得し、また空の配列に入れる。

そして、
空の配列によって、値を新たに定義できる。
for文によって、複数の配列を一気に処理できる。

## for文はすごいぞ!!

なんでfor文はすごいか？
for文で繰り返し処理によって、いろんな値を一気に処理できる!!!

できたことから話します。
`for文` を使って、できることは：
1. 取れた値を一つずつ点数を配布すること
2. さらにfor文を使って、その点数の配布を配列の中の配列に配布すること

```
const sample = {};

    for (let i = 0; i < samples.length; i++) {
    const sample = samples[i];
    const currentResult = {};

        for (let j = 0; j < sample.length; j++) {
        const currentQuestion = sample[j];
            if (reversedIndices.includes(j + 2)) {
                if (currentQuestion === "当てはまる") {
                 currentResult[j + 2] = 1;
                } else if (currentQuestion === "やや当てはまる") {
                currentResult[j + 2] = 3;
                } else if (currentQuestion === "どちらとも言えない") {
                currentResult[j + 2] = 5;
                } else if (currentQuestion === "やや当てはまらない") {
                currentResult[j + 2] = 8;
                } else if (currentQuestion === "当てはまらない") {
                currentResult[j + 2] = 10;
                }
                } else {
                if (currentQuestion === "当てはまる") {
                currentResult[j + 2] = 10;
                } else if (currentQuestion === "やや当てはまる") {
                currentResult[j + 2] = 8;
                } else if (currentQuestion === "どちらとも言えない") {
                currentResult[j + 2] = 5;
                } else if (currentQuestion === "やや当てはまらない") {
                currentResult[j + 2] = 3;
               } else if (currentQuestion === "当てはまらない") {
                currentResult[j + 2] = 1;
           }
         }
       }

          resultProblemSolving[i] = currentResult;
          }

```

この文を通して、解答の点数と逆転項目の点数(`reversedIndices`)をそれぞれ配布することができました。

### 
点数の合算などを省略させていただきますが、最後に、chart.jsの処理の前に、一旦処理後のデータをQ1-Q7resultsとして、配布していきます。

```
const array = [
                [0, 0],
                [0, 0],
                [0, 0],
                [0, 0],
                [0, 0]
                ];

                for (let i = 0; i < 5; i++) {
                   if (data[i] && data[i][0]) {
                       array[i][0] = data[i][182];
                    }
                    if (data[i] && data[i][0]) {
                        array[i][1] = Q1results[i];
(以下省略)
```
arrayの○番目の0番目、1番目が何を入れるかによって、最後のChart.jsの数字を変えます。
Chart.jsにあるサンプルコードを参考にこういうふうに：

```
 datasets: [{
             label: `${array[0][0]}`,
             data: [`${array[0][1]}`, `${array[0][2]}`, `${array[0][3]}`, `${array[0][4]}`,`${array[0][5]}`, `${array[0][6]}`, `${array[0][7]}`],
             fill: true,
             backgroundColor: 'rgba(75, 192, 192, 0.2)',
             borderColor: 'rgba(75, 192, 192, 1)',
             borderWidth: 1
             },
             {
             label: `${array[1][0]}`,
             data: [`${array[1][1]}`, `${array[1][2]}`, `${array[1][3]}`, `${array[1][4]}`,`${array[1][5]}`, `${array[1][6]}`, `${array[1][7]}`],
             fill: true,
             backgroundColor: 'rgba(54, 162, 235, 0.2)',
             borderColor: 'rgb(54, 162, 235)',
             borderWidth: 1
             },
             {
             label: `${array[2][0]}`,
             data: [`${array[2][1]}`, `${array[2][2]}`, `${array[2][3]}`, `${array[2][4]}`,`${array[2][5]}`, `${array[2][6]}`, `${array[2][7]}`],
             fill: true,
             backgroundColor: 'rgba(235, 127, 54, 0.2)',
             borderColor: 'rgb(235, 127, 54)',
             borderWidth: 1
             },
(以下省略)
```

`dataset`の中に、どんなデータがどういうふうに配置するの決めて、arrayの値を一つずつ振っていきます。そうするとイメージ通りに、取得したデータを処理へて、チャートを重なることができました。(バンザイ!!)

![スクリーンショット 2023-06-19 0.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959760/c2e44262-b5c9-0e1c-0c46-7cd81bd9ebe4.png)

P.S.
↑↑↑最後の部分↑↑↑が同期のあべ氏の教えがあったからできたし、そこから逆算して、配列への理解が深まった!! (感謝)

## 最後に、、、

ジーズを通っていた頃、毎週課題をこなし、好きなプロダクトを作って、できることもできないことも楽しんでいました。卒業してから、学んだことを仕事に落とし込むと、ハードルが一気に上がった。それでも、仕事上、コミットしなきゃいけないので、必然人に聞いて、最後までやるしかないのです!!

結論！！
完成しなきゃいけない環境にいると、嫌でも書けるようになるんだ！！ (締め切りに追われ、痛感)
そして、もっと早く配列と仲良くなればよかった!!! 

幸い、この機会があって、抽出データを思う存分調理できる自分になることが嬉しかったです〜。
だから、、、またなんか作ります ^^

**参考資料** 
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典：配列

https://wa3.i-3-i.info/word11924.html

二次元配列

http://ysklog.net/java/5-18.html

Radar Chart

https://www.chartjs.org/docs/latest/charts/radar.html

Slice関数

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice