息を吐くようにかけるようになりたいJavaScriptの記述

書く機会の多いものなら、スラスラ書ける方がいいので、毎日の練習と思ってここに書き溜めておきます。

## Case 1...オブジェクトのKeyだけ配列にしたい

ObjectのKeyだけの配列を取り出したい時

```js
const members = {
  lerder: "tom",
  member: "sam"
};

// この変数に格納して console.log してください
const roles
console.log(roles);
```

### Answer 1

```js
const roles = Object.keys(members)
console.log(roles); // => ["lerder", "member"]
```

## Case 2...Array Object と Mapメソッド 

大学学年別の所属メンバーの1年生（freshman）だけ、敬称した名前だけ配列に格納したい時。

```js
// 大学の学年別の所属メンバー
const members = {
  freshman: ["佐藤", "加藤", "伊藤"],
  junior: ["岡田", "前田", "上田"]
};

// 名前に様つける関数
const addHonorificTitle = name => {
  return `${name}様`;
};

// この変数に格納して console.log してください
const names;
console.log(names);
```

### Answer 2

```js
const names = members.freshman.map(member => addHonorificTitle(member));
console.log(names); // => ["佐藤様", "加藤様", "伊藤様"]
```

できたら、省略して書きたい。
`map`のコールバック関数内は引数と、何かの関数内の引数が同じな場合は省略できる。

```js
const names = members.freshman.map(addHonorificTitle);
console.log(names); // => ["佐藤様", "加藤様", "伊藤様"]
```

## Case 3...forEach

三角形の底辺と高さのオブジェクトの集合を配列にしたデータ（Array in Object）が`triangles`という変数名に格納されています。
このデータの中に各三角形の面積（底辺×高さ÷2）の結果を`areas`変数名を追加する処理を書いてください。

```js
const triangles = [
  { base: 10, height: 10 },
  { base: 20, height: 20 },
  { base: 30, height: 30 }
];

// 何かの処理
console.log(triangles)
```

### Answer 3

```js
triangles.forEach((triangle) => {
  triangle.areas = (triangle.base * triangle.height) / 2
});

// [Object, Object, Object]
// 0: Object
//   base: 10, height: 10, areas: 50
// 1: Object
//   base: 20, height: 20, areas: 200
// 2: Object
//   base: 30, height: 30, areas: 450
```

色々な方法で実装が可能だとは思いますが、なぜ`forEach`を使用したかの説明をします。

`forEach`は戻り値を持たないので、何かの処理を実現しようとすると外部スコープに対する操作が前提になります。文脈次第ですが、変数`triangles`に三角形の合計である`areas`のデータが追加されても致命的なエラーは起こしにくいのではと考えてこう実装しました。ただし、基本的には外部スコープのデータを書き換えてしまうので、注意は必要です。

### 参考

- [JavaScriptのmapとforEachの使い分け](https://yukimonkey.com/data/map-foreach/#h2_3)
- [JavaScript で forEach を使うのは最終手段 \- Qiita](https://qiita.com/diescake/items/70d9b0cbd4e3d5cc6fce)

## Case 4...pluck

Railsのメソッド`pluck`にあるような[関数を](https://railsguides.jp/active_record_querying.html#pluck)作ってください。
仕様

- とる引数は2つ（arrayObject, objectのプロパティ名）
- objectのvalue一覧を新たな配列で返す

```js
const memberObjects = [
  { id: 1, name: "田中" },
  { id: 2, name: "中村" },
  { id: 3, name: "村山" },
  { id: 4, name: "山川" },
  { id: 5, name: "川本" }
];

const pluck = // 要件を満たすような関数を作成してください;

const memberNames = pluck(memberObjects, "name");

console.log(memberNames); // => ["田中", "中村", "村山", "山川", "川本"]
```

### Answer 3

```js
const memberObjects = [
  { id: 1, name: "田中" },
  { id: 2, name: "中村" },
  { id: 3, name: "村山" },
  { id: 4, name: "山川" },
  { id: 5, name: "川本" }
];

const pluck = (arrayObject, propertyName) => {
  return arrayObject.map(object => object[propertyName]);
};

const memberNames = pluck(memberObjects, "name");

console.log(memberNames); // => ["田中", "中村", "村山", "山川", "川本"]
console.log(memberObjects); // => 元の状態のままです
```

`map`の特徴の1つとして、イミュータブルなところがあります。イミュータブルとは、オブジェクトの状態が変わらないことを意味します。イミュータブルなコーディングが意識されたプロジェクトの利点は、データの状態や挙動の見通しが良くなる点が挙げられます。つまり、データは作成されたときのままであることが保証されます。

`map`は、元の配列を書き換えず別の新たな配列を作成するので、イミュータブルな処理をすることができます。

## Case 5...分割代入とその参照

下記のオブジェクトのプロパティ`name`だけ分割代入したいとき

```js
const memberObjects = { id: 1, name: "川本" };
```

### Answer 5

```js
const { name } = memberObjects;
console.log(name);
```

（注意）プロパティの名前を変数の名前は一致させる必要があります。

では、`name`でなく、`memberName`という変数名に代入したい場合は？どう書けばいいでしょうか？

```js
const { name: memberName } = memberObjects;
console.log(memberName); // => 川本
```

## Case 6...オブジェクトの参照

`object.value`の値を`minus`関数を用いて`-1`したいとします。
しかし、値は変わりません（`10`）でした。どうすれば値を変更（`9`に）できるでしょうか？

```js
let object = { value: 10 };
const minus = ({ value }, val) => (value = value - val);
minus(object, 1);
console.log(object.value); // => 10
```

問題点、`minus`関数の第一引数に変数代入している時点で、最初に宣言した`object.value`とは別のメモリ格納先の値になっています。

### Answer 6

問題点に指摘した通りで、解決方法は、1行目で宣言した値を参照するようにする。

```js
let object = { value: 10 };
const minus = ({ value }, val) => (object.value = value - val);
minus(object, 1);
console.log(object.value); // => 9
```

## Case 7...オブジェクトの参照と等価

`through`関数を通して格納された`object2`と`object`は等価（厳密比較して`true`になる）でしょうか？

```js
let object = { value: 10 };
const through = (object) => object;
const object2 = through(object);
console.log(object === object2); // true OR false
```

### Answer 7

答え　`true`
理由　`object` と `object2` は同じ参照先なので（プロミティブ型では値の比較で、オブジェクトでは参照の比較なので）。

## Case 8...ビートルズのアルバムだけ抜き出したい

以下のようなデータがあるとします。`albumTitles`には、ビートルズのアルバムのタイトルもあれば、マイケルジャクソンやスティービーワンダーのも混じっています。これを `albumTitles` は配列なので `filter` を使って、ビートルズのアルバムのタイトルだけのArrayObjectを作ってください。

```js
const artist = { id: 1, name: "beatles" };

const albumTitles = [
  { artistId: 1, name: "Revolver" },
  { artistId: 1, name: "Sgt. Pepper's Lonely Hearts Club Band" },
  { artistId: 1, name: "Magical Mystery Tour" },
  { artistId: 2, name: "Innervisions" },
  { artistId: 2, name: "Key of Life" },
  { artistId: 3, name: "Thriller" },
  { artistId: 3, name: "Bad" },
  { artistId: 3, name: "Invincible" }
];

// この変数に格納して console.log してください
const selectAtistAlbums 
const result = selectAtistAlbums();
console.log(result);
```

### Answer 8

```js
const selectAtistAlbums = ({ id: artistIdParam }, albumTitles) => {
  return albumTitles.filter(({ artistId }) => artistId === artistIdParam);
};
const result = selectAtistAlbums(artist, albumTitles);
console.log(result); // => [Object, Object, Object]
//
// 0: Object
//    artistId: 1
//    name: "Revolver"
// 1: Object
//    artistId: 1
//    name: "Sgt. Pepper's Lonely Hearts Club Band"
// 2: Object
//    artistId: 1
//    name: "Magical Mystery Tour"
```

ビートルズのアルバムだけ抜き出せましたね。

## Case 9...reduceの練習(1)

ここからは、`reduce`の練習です。配列操作系の万能メソッド `reduce` を使って、配列 `numbers` の値を1つづつ足してください。引数名はなんでもいいです。

```js
const numbers = [1, 2, 3];

// この変数に格納して console.log してください
const result;

console.log(result);
```

### Answer 9

```js
const numbers = [1, 2, 3];

const result = numbers.reduce((accumlator, currentValue) => {
  return accumlator + currentValue;
}, 0);

console.log(result); // => 6
```

## Case 10...reduceの練習(2)

また`reduce`の練習です。 `reduce` を使って、配列 `numbers` にある数値の中で最大値を返すアロー関数を作成してください。引数名はなんでもいいです。

```js
const numbers = [1, 10, 300, 100, 20];

// この変数に格納して console.log してください
const result;

console.log(result);
```

### Answer 10

```js
const numbers = [1, 10, 300, 100, 20];

// この変数に格納して console.log してください
const result = numbers.reduce((previousValue, currentValue) => {
  if (previousValue < currentValue) {
    return currentValue;
  } else {
    return previousValue;
  }
});

console.log(result);
```

`reduce`第二引数が指定されていない場合、`numbers`の一番最初の関数実行時のpreviousValueが第二引数の初期値になる。

## Case 11...reduceの練習(3)

また`reduce`の練習です。 `reduce` を使って、以下のArrayObjectが格納されている変数`types`の各要素のプロパティtype毎のカウント数をObjectとして返す関数を`result`に格納してください。引数名はなんでもいいです。

```js

const types = [ { type: "A" },{ type: "B" },{ type: "B" },{ type: "B" },{ type: "C" },{ type: "C" } ];

// この変数に格納して console.log してください
const result;

console.log(result);

```

### Answer 11

```js

const types = [ { type: "A" },{ type: "B" },{ type: "B" },{ type: "B" },{ type: "C" },{ type: "C" } ];

// この変数に格納して console.log してください
const result = types.reduce(
  (accumlator, current) => {
    if (current.type === "A") accumlator.typeA++;
    if (current.type === "B") accumlator.typeB++;
    if (current.type === "C") accumlator.typeC++;
    return accumlator;
  },
  { typeA: 0, typeB: 0, typeC: 0 }
);

console.log(result);

```