概要
最近、js で配列の中身をforで回す人をよく見かける。
map や reduce はよく使うので知っておいてもらいたい。
map
mapは元の配列から新しい配列を生成する関数。
const array = [1, 2, 3, 4];
const output = array.map(x => x * 2);
console.log(output);
[ 2, 4, 6, 8 ]
自分は以下のインラインコールバック関数を一番使用する。
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とほぼ一緒だが、ただ単に処理を行うメソッドであり、配列を返さない。
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は指定した条件に該当する値の配列を生成する。
const array = ['34', '54', '11', '83', '23', '63'];
const result = array.filter(x => x > 50);
console.log(result); // Array ["54", "83", "63"]
こちらもmap同様インラインコールバック関数を使用できる。
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
とほぼ同じだが、条件に当てはまるものが1つ見つかった時点でそれを返す。
const array = ['34', '54', '11', '83', '23', '63'];
const result = array.find(x => x > 50);
console.log(result); // 54
every
こちらもfilter
に似ているが、配列の要素すべてが条件に当てはまったらtrue、1つでも当てはまらなかったらfalseを返す。
const array = ['34', '54', '11', '83', '23', '63'];
const result = array.every(x => x > 50);
console.log(result); // false
some
everyと違い、配列の要素1つでも条件に当てはまったらtrue、全て当てはまらなかったらfalseを返す。
const array = ['34', '54', '11', '83', '23', '63'];
const result = array.some(x => x > 50);
console.log(result); // true
reduce
reduceは配列のそれぞれの要素に対してインラインコールバック関数を適用した最終的な結果を返す。
回帰みたいな感じなのをやってくれる。
以下の例が一番代表的でわかりやすい。引数のsumにはその前の要素までの計算結果が入る
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 は配列みたいのもの。ただし、重複は許されない。
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 ]
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とは全く別物である。
const map = new Map([["key1", "value1"], ["key2", "value2"]]);
console.log(map.size); // 2
console.log(map); // Map(2) { 'key1' => 'value1', 'key2' => 'value2' }
lodash
インストールして、インポートする必要がある。
import _ from 'lodash';
上記のように全部インストールするよりも、使用したい関数をimport shuffle from "lodash/shuffle";
のようにインポートするのがおすすめ。
lodashは配列処理で便利な関数が集まっている。
参考 : [JavaScript] 配列の操作はLodashを使いこなせると便利
実践例
重複してるものを無くす
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 ]
検索
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でできる。
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で作れる
const arrA = [1, 4, 2];
const arrB = [5, 2, 7, 1];
const res = arrA.filter(it => arrB.includes(it));
console.log(res); // [ 1, 2 ]