☀️

javascript の some every を 空配列で実行した話

2022/04/21に公開
2

今回の話

javascript の超便利メソッド some, every 自分も普段からよく使うのですが、空の配列で実行した時に期待する挙動と違うことがあり記事にしました。
百聞は一見に如かずということで早速コードとデモを次に記載します。

コード

下記のコードでは some と every をそれぞれから配列で実行してその結果をコンソールに出力しています。

var hoge = [];
var fuga = 'aaaaaa';
var every_result_1 = hoge.every(h => h === fuga);
var some_result_1 = hoge.some(h => h === fuga);
console.log('every_result_1', every_result_1);
console.log('some_result_1', some_result_1);

出力結果

every_result_1 true
some_result_1 false

期待していた結果としては some every いずれも false が返ってくることだったのですが、ご覧のように every では true が返ってきています。
思わぬバグの原因になりかねないので、要注意です。

デモ

some every テスト | Runstant

Discussion

nap5nap5

公式では走査対象のアイテム配列が空配列の場合だと、trueを返すようです

期待する振る舞いを得たい場合はラップしてみるのがいいかもですね。

定義側

import { dequal } from "dequal";

export const isSomeMatched = <T = unknown>(data: ReadonlyArray<T>, item: T) => {
  return data.some(d => dequal(d, item))
}

export const isAllMatched = <T = unknown>(data: ReadonlyArray<T>, fn: (d: T) => boolean) => {
  if (data.length === 0) return false
  return data.every(fn)
}

使用側

test("isAllMatched", () => {
  const items: ReadonlyArray<{}> = [];
  const inputData = { id: "3", name: "Orange" };
  const outputData = isAllMatched(items, (d) => dequal(d, inputData));
  expect(outputData).toStrictEqual(false);
});

test("isSomeMatched", () => {
  const items = [
    { id: "1", name: "Apple" },
    { id: "2", name: "Banana" },
    { id: "3", name: "Orange" },
  ];
  const inputData = { id: "3", name: "Orange" };
  const outputData = isSomeMatched(items, inputData);
  expect(outputData).toStrictEqual(true);
});

demo code.

https://codesandbox.io/p/sandbox/peaceful-sara-5w8h8l?file=/src/index.ts:1,1

yutoyuto

ありがとうございます!
同じケースがあればラップして試してみます!