これだけは知っててほしいJavaScript 〜配列処理〜


# 概要

最近、**js** で配列の中身をforで回す人をよく見かける。
**map**　や **reduce**　はよく使うので知っておいてもらいたい。

# map

[map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)は元の配列から新しい配列を生成する関数。

```js
const array = [1, 2, 3, 4];
const output = array.map(x => x * 2);
console.log(output);
```

```:実行結果
[ 2, 4, 6, 8 ]
```

自分は以下のインラインコールバック関数を一番使用する。

```js
const array = ["a", "b", "c"];

array.map(function(value,index,arr) {
    console.log(value, index, arr);
})
```

```:実行結果
a 0 [ 'a', 'b', 'c' ]
b 1 [ 'a', 'b', 'c' ]
c 2 [ 'a', 'b', 'c' ]
```

# forEach

forEachはmapとほぼ一緒だが、ただ単に処理を行うメソッドであり、配列を返さない。

```js
const array = [1, 2, 3];
const res = array.forEach(function(value,index,arr) {
    console.log(value, index, arr);
    return array * 2;
})
console.log(res);
```

```:実行結果
1 0 [ 1, 2, 3 ]
2 1 [ 1, 2, 3 ]
3 2 [ 1, 2, 3 ]
undefined
```

# filter

[filter](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)は指定した条件に該当する値の配列を生成する。

```js
const array = ['34', '54', '11', '83', '23', '63'];
const result = array.filter(x => x > 50);
console.log(result); // Array ["54", "83", "63"]
```

こちらもmap同様インラインコールバック関数を使用できる。

```js
const array = [3, 1, 5];
const result = array.filter(function(val, index, arr){
    console.log(val,index, arr)
    return val > 2;
})
console.log(`result: ${result}`);
```

```:実行結果
3 0 [ 3, 1, 5 ]
1 1 [ 3, 1, 5 ]
5 2 [ 3, 1, 5 ]
result: 3,5
```


# find

`filter`とほぼ同じだが、条件に当てはまるものが１つ見つかった時点でそれを返す。

```js
const array = ['34', '54', '11', '83', '23', '63'];
const result = array.find(x => x > 50);
console.log(result); // 54
```

# every

こちらも`filter`に似ているが、配列の要素すべてが条件に当てはまったらtrue、１つでも当てはまらなかったらfalseを返す。

```js
const array = ['34', '54', '11', '83', '23', '63'];
const result = array.every(x => x > 50);
console.log(result); // false
```

# some

everyと違い、配列の要素１つでも条件に当てはまったらtrue、全て当てはまらなかったらfalseを返す。

```js
const array = ['34', '54', '11', '83', '23', '63'];
const result = array.some(x => x > 50);
console.log(result); // true
```


# reduce

reduceは配列のそれぞれの要素に対してインラインコールバック関数を適用した最終的な結果を返す。
回帰みたいな感じなのをやってくれる。

以下の例が一番代表的でわかりやすい。引数のsumにはその前の要素までの計算結果が入る

```js
var numbers = [1,2,3];
var result = numbers.reduce(function(sum, num, index, arr) {
    console.log(sum, num, index, arr);
    return sum + num;
})
console.log("result : " + result);
```

```:実行結果
1 2 1 [ 1, 2, 3 ]
3 3 2 [ 1, 2, 3 ]
result : 6
```

# Set

[Set](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set) は配列みたいのもの。ただし、重複は許されない。

```js
const set = new Set([1, 2, 3]);
const array = [1, 2, 3];

console.log(set); // Set(3) { 1, 2, 3 }
console.log(array); // [ 1, 2, 3 ]
```

```js
const set = new Set([1, 2, 3]);
mySet1.add(4)  // Set [ 1, 2, 3, 4 ]
set.size // 4
mySet1.has(1)   // true
mySet1.delete(4)  // Set([1, 2, 3]);
```


# Map

Mapはmapとは全く別物である。
```js
const map = new Map([["key1", "value1"], ["key2", "value2"]]);
console.log(map.size); // 2
console.log(map); // Map(2) { 'key1' => 'value1', 'key2' => 'value2' }
```

# lodash

インストールして、インポートする必要がある。

```js
import _ from 'lodash';
```

上記のように全部インストールするよりも、使用したい関数を`import shuffle from "lodash/shuffle";`のようにインポートするのがおすすめ。 
lodashは配列処理で便利な関数が集まっている。

参考 : [[JavaScript] 配列の操作はLodashを使いこなせると便利](https://dev.classmethod.jp/articles/nodejs-array-manipulation-is-useful-if-you-master-lodash/)


# 実践例

## 重複してるものを無くす

```js
const values = [4, 6, 7, 3, 1, 7, 4, 2, 3, 7];
const result = [...new Set(values)];
console.log(result) // [ 4, 6, 7, 3, 1, 2 ]
```

## 検索

```js
const users = [
  { name: 'Ichiro', age: 23 },
  { name: 'Jiro', age: 28 },
  { name: 'Saburo', age: 34 },
  { name: 'Shiro', age: 28 }
];
// 大文字小文字区別する
let res1 = users.filter(it => it.name.includes('I'));
// 大文字小文字区別しない
let res2 = users.filter(it => new RegExp('I', "i").test(it.name));

console.log(res1);
console.log(res2);
```

```:実行結果
[ { name: 'Ichiro', age: 23 } ]
[
  { name: 'Ichiro', age: 23 },
  { name: 'Jiro', age: 28 },
  { name: 'Shiro', age: 28 }
]
```


## A ∪ B

**lodash** の *union* をわざわざインポートしなくても**Set**でできる。

```js
const arrA = [1, 4, 2];
const arrB = [5, 2, 7, 1];
const res = [...new Set([...arrA, ...arrB])];
console.log(res); // [ 1, 4, 2, 5, 7 ]
```

## A ∩ B

こちらもlodashを使わなくても、filterで作れる

```js
const arrA = [1, 4, 2];
const arrB = [5, 2, 7, 1];
const res = arrA.filter(it => arrB.includes(it));
console.log(res); // [ 1, 2 ]
```