💩

忘れるのでArray.methodsのメモ✍️

2023/10/05に公開

What's this?

配列の持つ以下のメソッドが「書き方によって同じことができるけど、こっちの方がスマートだよね」と指摘されるので書き出していく感じです。(es2023で増えたので)

every();
filter();
find();
findLast();
findIndex();
findLastIndex();
some();

早見表

メソッド名 条件に(1つでも)合致した場合の戻り値 条件に(1つも)合致しない場合の戻り値
every true false
filter Array 空配列
find 最初に合致した配列要素 undefined
※ findLast 最後に合致した配列要素 undefined
findIndex 最初に合致した要素のインデックス -1
※ findLastIndex 最後に合致した要素のインデックス -1
some true false

※ es2023で追加されたメソッド https://tc39.es/ecma262/2023/#sec-intro

各メソッドの説明コメント付きサンプル

class Numbers extends Array<number> {

    private readonly list: number[];  // 操作対象

    constructor(arr: Array<number>) {
        super(...arr);
        this.list = arr;
    }

    lessThanOne(): boolean {
        /**
         * 「every = あらゆる、すべての」の表す通り、全要素が条件に合致する・しないをbooleanで返します。
         */
        return this.list.every(element => element < 1);
    }

    orMore(border: number): number[] {
        /**
         * 条件に合致した要素だけの配列のシャローコピーを返します。
         * ~~他のメソッドを忘れるすべての元凶。~~
         */
        return this.list.filter(element => element >= border);
    }

    orMoreHead(border: number): number | undefined {
        /**
         * 最初に条件に合致したものだけを返します
         */
        return this.list.find(element => element >= border);
    }

    orMoreTail(border: number): number | undefined {
        /**
         * 最後に条件に合致したものだけを返します
         */
        return this.list.findLast(element => element >= border);
    }

    isIn(test: unknown): boolean {
        /**
         * 1つでも条件に合致すればtrueを返す
         */
        return this.list.some(element => test === element);
    }
}

const arr = [1, 0, 100, -2152, Number.MIN_SAFE_INTEGER, 100];

const numbers = new Numbers(arr);

type hoge = (typeof arr)[number];

console.log(numbers.lessThanOne()); // false
console.log(numbers.orMore(0)); // [1, 0, 100, 100]
console.log(numbers.orMoreHead(1)); // 1
console.log(numbers.orMoreTail(1)); // 100

/**
 * この2行は同じく2を返す。
 */
console.log(numbers.indexOf(100));
console.log(numbers.findIndex(element => element === 100));

/**
 * この2行は同じく5を返す。
 */
console.log(numbers.lastIndexOf(100));
console.log(numbers.findLastIndex(element => element === 100));

console.log(numbers.isIn(1)); // true
console.log(numbers.isIn(999)); // false
console.log(numbers.isIn("aaa")); // false


/**
 * おまけ
 * プリミティブな配列内に値が存在するか見るのにsome()で見た目よく書けるのではという話
 * meta.find()の戻り値は型情報としてbooleanは持たないためタイプガード関数でエラーになる。
 * 
 * 使い分けできると、コーディング時にあれ?とならなくて良いかなと
 */

const meta = ["hoge", "hoo", "bar"] as const;

type Meta = typeof meta[number];

const isMetasyntactic = (test: unknown): test is Meta => {
    return meta.some((keyword) => keyword === test);
}

const keyword = "hoge";
if (isMetasyntactic(keyword)) { console.log(keyword) }

TypeScript Playgroundで動作させる場合にはこちら

その際には、TS config > TargetをESNextに変更してください(2023/10/05時点)

終わりに

気を抜くと片っ端からfilter()で書こうとする自分がいるので整理のためにも書いた。
ついでに、まだそんなに触れてないES2023の内容も洗えたのでヨシ!

Discussion