たまに忘れるので備忘録として残します。
主には、配列メソッドのinclude
を使います。
includes
配列に特定の要素が含まれているかどうかを調べて、true/falseで結果を返す。
const array1 = [1, 2, 3]
console.log(array1.includes(2)) // true
サンプル
こんな配列データがあったとします。
// 全リスト
const list = [
{id: 1, name: 'A'},
{id: 2, name: 'B'},
{id: 3, name: 'C'},
{id: 4, name: 'D'},
]
// 登録済みだけのリスト
const registeredList = [
{id: 2, name: 'B'},
{id: 4, name: 'D'},
]
ケース1
listを登録処理する際に、登録済みのregisteredListは登録不要なのでfilterして除去したい時
const filteredList = list.filter(value => {
// 判定用にidだけの配列を用意する
const targetIds = registeredList.map(v => v.id)
return !targetIds.includes(value.id)
})
// 結果はこうなります
[
{id: 1, name: 'A'},
{id: 3, name: 'C'}
]
ケース2
すべてのデータが登録済みなら登録ボタンを押せなくしたいので、listのデータと登録済みのregisteredListを比較して、すべて登録済みかを判定したい
// 判定用にidだけの配列を用意する
const targetIds = registeredList.map(b => b.id)
// everyメソッドは全ての要素がコールバックに合格するかでtrue/falseを返す
const result = list.every((value) => targetIds.includes(value.id))
// 結果はfalseです。もしregisteredListのデータをlistと同じにすればtrueとなります
ケース3
ケース1, 2ともに判定用にidだけの配列を用意し、includesメソッドを使っていますが、別のやり方としてidをキーにしたRecordデータ { KEY1: {}, KEY2: {} }
を用意して、検索対象のidがキーの中に含まれるかどうかを検索すると言う方法もあります。得られる結果は同じなのですが、データ量が数千件規模と多くなるほどこの方法がの方が速く、存在チェックではよくある手法らしいので紹介します。
再度ケース1(listを登録処理する際に、登録済みのregisteredListは登録不要なのでfilterして除去したい時)をこのやり方でやってみます。
// 判定用にidをキーにしたRecordデータを用意する
const registeredListMap = {}
registeredList.forEach(r => registeredListMap[r.id] = r)
// こういうオブジェクトができます
{
2: {id: 2, name: 'B'},
4: {id: 4, name: 'D'},
}
const filteredList = list.filter(value => {
// registeredListMapに存在しないIDでアクセスすればundefinedが返る
// 存在しない(= 登録してない)データだけを抽出する
return !registeredListMap[value.id]
})
// 結果はこうなります
[
{id: 1, name: 'A'},
{id: 3, name: 'C'}
]
他にもやり方や、違う比較のケースなどあると思うので、追って追加して行きます。