LoginSignup
57
17

More than 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

【TypeScript/JavaScript】配列操作、利用数順に紹介

Last updated at Posted at 2023-06-26

TypeScript/JavaScriptの配列操作について、私たちのとあるリポジトリ内での利用順に紹介します。
一度も利用されていない操作は載せていないので悪しからず。

関数 利用数
map() 267
filter() 122
push() 120
some() 68
join() 49
reduce() 38
flatMap() 33
find() 31
includes() 24
every() 17
flat() 13
slice() 12
forEach() 11
reverse() 5
sort() 2
concat() 2
pop() 1
splice() 1
unshift() 1

map

mapは、与えた関数を配列のすべての要素に適用させて新しい配列を生成します。

map
const before = [1, 2, 3];
const after = before.map(v => v * 2);
console.log(after); // [2, 4, 6]

filter

filterは、与えられた条件に合致する要素のみに絞り込んだ配列を返します。

filter
const before = [1, 2, 3];
const after = before.filter(v => v % 2 === 0);
console.log(after); // [2]

TypeScriptの場合、
型ガードと合わせると便利です。

型安全なfilter
const before = [1, undefined, 3, 4, undefined];

// [1, 3, 4]に絞り込めているが推論される型は(number | undefined)[]のまま
const after = before.filter(v => !!v);

// vがnumberであることを返すため、number[]となる
const safeAfter = before.filter((v): v is number => !!v);

なお、filterの戻り値はシャローコピーです。

シャローコピー
const before = [
    { name: 'aaa', age: 10 },
    { name: 'bbb', age: 20 },
    { name: 'ccc', age: 30 },
];
const after = before.filter(v => v.age >= 20);
console.log(after); // [{ "name": "bbb", "age": 20 }, { "name": "ccc", "age": 30 }] 

// after[0]のnameを変えると、before[1]のnameも変わっている
after[0].name = 'XXX';
console.log(before[1]); // { "name": "XXX", "age": 20 } 

push

pushは、配列の末尾に要素を追加します。なお、引数は可変長引数なので、1つ以上の要素を追加できます。

push
const ary = [1];
ary.push(2);
ary.push(3, 4, 5, 6);
console.log(ary); // [1, 2, 3, 4, 5, 6] 

some, every, includes

似た処理なのでまとめて説明します。

someは、与えられた条件合致する要素が一つ以上あるかの判定処理です。
everyは、与えられた条件すべての要素が合致するかの判定処理です。
includesは、特定の要素が配列に含まれているかの判定処理です。

some, every, includes
const ary = [1, 1, 1, 2];

console.log(ary.some(v => v % 2 === 0));  // true
console.log(ary.every(v => v % 2 === 0)); // false
console.log(ary.includes(2));             // true

join

joinは、配列のすべての要素を指定した区切り文字で連結した文字列を返します。
なお、区切り文字のデフォルトは,となっており、省略が可能です。

join
const ary = [1, 2, 3];

console.log(ary.join());    // "1,2,3"
console.log(ary.join(',')); // "1,2,3"
console.log(ary.join('_')); // "1_2_3"

reduce

reduceは、配列の要素を順番に処理して、単一の値に累積していく操作です。
reduce(callbackFn, initialValue)の形で記述します。

reduce
const ary = [1, 2, 3, 4];
const sum = ary.reduce((p, c) => p + c, 0);
console.log(sum); // 10

詳しくは、手前味噌ですが、【TypeScript/JavaScript】配列操作reduce()を救いたい。をご参照くださいませ。

flatMap, flat

flatMapの前にflatの説明をしてしまう方が分かりやすいので一緒に説明します。

flat

flatは、ネストした配列を指定した深さで結合した新しい配列を生成します。
深さはデフォルト1となっており省略可能です。

flat
const ary = [1, 2, [3, [4]]];

console.log(ary.flat());  // [1, 2, 3, [4]]
console.log(ary.flat(2)); // [1, 2, 3, 4]

flatMap

flatMapは、与えた関数を配列のすべての要素に適用させた後に深さ1のflatを適用する処理です。
つまり、ary.map().flat()ary.flatMap()は同じ結果が得られます
(MDNによると、ary.map().flat()よりもary.flatMap()のほうがわずかに効率的らしいです。)

flatMap
const ary = [
    "I am a student",
    "He walks his dog every morning",
];

// map
// [["I", "am", "a", "student"], ["He", "walks", "his", "dog", "every", "morning"]] 
const mapAry = ary.map(v => v.split(' '));
console.log(mapAry);

// map + flat
// ["I", "am", "a", "student", "He", "walks", "his", "dog", "every", "morning"] 
const mapFlatAry = ary.map(v => v.split(' ')).flat();
console.log(mapFlatAry)

// flatMap
// ["I", "am", "a", "student", "He", "walks", "his", "dog", "every", "morning"] 
const flatMapAry = ary.flatMap(v => v.split(' '));
console.log(flatMapAry);

find

findは、与えられた条件に合致する最初の要素を返します。
合致する要素が存在しない場合はundefinedを返します。

find
const ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(ary.find(v => v % 2 === 0)); // 2
console.log(ary.find(v => v > 100));     // undefined

slice, splice

名前が似てるので一緒に説明します。

sliceは、配列から指定した範囲の要素で新しい配列を生成します。
対して、spliceは、配列に対して指定した範囲で、要素を追加したり、削除したりすることで、配列の内容を変更します。

slice

sliceは、ary.slice(start, end)の形で記述し、start,endともに省略が可能です。
なお、endで指定したインデックスの要素は含まれません。
返り値は、取り出された範囲の要素の新しい配列になります。

slice
const ary = [0, 1, 2, 3, 4, 5, 6];

console.log(ary.slice(1, 2)); // [1]
console.log(ary.slice(3));    // [3, 4, 5, 6]
// 元の配列はそのまま
console.log(ary);             // [0, 1, 2, 3, 4, 5, 6]

なお、sliceで生成された配列はシャローコピーです。

splice

spliceは、ary.splice(start, deleteCount, itemN)の形で記述し、deleteCount及びitemNは省略可能です。
startが変更開始の位置、deleteCountは取り除く要素数、itemNは追加する要素です。
deleteCountが省略された場合、操作範囲はstartから末尾までとなります。
返り値は、取り除かれた要素を含む配列です。また、操作元の配列からその要素は取り除かれる点に注意してください。

splice
const ary = [0, 1, 2, 3, 4, 5, 6];

// インデックス1から要素を2個取り除く
console.log(ary.splice(1, 2));     // [1, 2]
console.log(ary);                  // [0, 3, 4, 5, 6]

// インデックス3から末尾までの要素を取り除く
console.log(ary.splice(3));        // [5, 6]
console.log(ary);                  // [0, 3, 4]

// インデックス1から要素を1個取り除き、そこに99,100,101を追加する
console.log(ary.splice(1, 1, 99, 100, 101)); // [3]
console.log(ary);                  // [0, 99, 100, 101, 4] 

forEach

forEachは、配列のすべての要素に順番に与えられた関数を実行します。

forEach
const ary = [1, 2, 3];
ary.forEach(v => console.log(v);

reverse

reverseは、配列を反転させます。
返り値は、反転した配列ですが、元の配列も反転しています。

reverse
const ary = [1, 2, 3];
const reversed = ary.reverse();
console.log(reversed); // [3, 2, 1]
console.log(ary);      // [3, 2, 1]

sort

sortは、配列の要素を任意の比較関数に従ってソートします。
返り値は、ソートされた配列ですが、元の配列もソートされています。

sort
const ary = [1, 20, 3, 400, 5, 60];

console.log(ary.sort((a, b) => a - b )); // [1, 3, 5, 20, 60, 400]
console.log(ary);                        // [1, 3, 5, 20, 60, 400]

concat

concatは、2つ以上の配列を結合して、新しい配列を返します。

concat
const ary1 = [1, 2, 3];
const ary2 = [100, 200, 300];

const concatAry = ary1.concat(ary2);
console.log(concatAry); // [1, 2, 3, 100, 200, 300]
console.log(ary1);      // [1, 2, 3]

スプレッド構文を用いた書き方のほうが現在は一般的かもしれないですね。

スプレッド構文を用いた配列の結合
const ary1 = [1, 2, 3];
const ary2 = [100, 200, 300];

const ary3 = [...ary1, ...ary2];
console.log(ary3); // [1, 2, 3, 100, 200, 300]

pop

popは、配列から最後の要素を取り除き、その要素を返します。

pop
const ary = [1, 2, 3, 4, 5];

console.log(ary.pop()); // 5
console.log(ary.pop()); // 4
console.log(ary.pop()); // 3

unshift

unshiftは、配列の先頭に要素を追加します。

unshift
const ary = [1, 2];

ary.unshift(100, 101, 102);
ary.unshift(99);

console.log(ary); // [99, 100, 101, 102, 1, 2]

参考

MDN Web Docs - Array

57
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
57
17