JavaScriptでオブジェクトの配列を別のフィルター配列を使って絞り込む方法
はじめに
本記事では、JavaScriptで「オブジェクト(連想配列)の配列」を、別の配列に含まれるキーと値のペアを条件としてフィルタリングする方法を解説します。
まず、次のような2つの配列があるとします。1つ目はデータ本体となる配列、2つ目はフィルター条件を格納した配列です。
const data = [
{"XD_A":"XDL","XD_B_1":"38","XD_B_2":"PB"},
{"XD_A":"XDR","XD_B_1":"51","XD_B_2":"PB"},
{"XD_A":"XDL","XD_B_1":"58","XD_B_2":"PB"},
{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"},
{"XD_A":"XDL","XD_B_1":"76","XD_B_2":"PB"},
{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"}
];
const filters = [{"XD_A":"XDR"},{"XD_B_1":"38"}];ここで求められているのは、第1引数にデータ配列、第2引数にフィルター配列を受け取るJavaScript関数です。
この関数は、データ配列の中からフィルター配列に存在するすべてのキーと値のペアを含むオブジェクトだけを抜き出し、それらを新しい配列にまとめて返す必要があります。
上記の配列の場合、返される配列は次のように、ちょうど2つのオブジェクトを含むことになります。
const output = [
{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"},
{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"}
];実装例
実際のコードは以下の通りです。
const data = [
{"XD_A":"XDL","XD_B_1":"38","XD_B_2":"PB"},
{"XD_A":"XDR","XD_B_1":"51","XD_B_2":"PB"},
{"XD_A":"XDL","XD_B_1":"58","XD_B_2":"PB"},
{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"},
{"XD_A":"XDL","XD_B_1":"76","XD_B_2":"PB"},
{"XD_A":"XDR","XD_B_1":"38","XD_B_2":"PB"}
];
const filters = [{"XD_A":"XDR"},{"XD_B_1":"38"}];
const filter = (data, filters) => {
return data.filter(e => {
try {
filters.forEach(o => {
Object.keys(o).forEach(key => {
if(e[key] !== o[key]) throw new Error();
});
});
return true;
}
catch(err) {
return false;
}
});
}
console.info(filter(data, filters));出力結果
コンソールには次のように表示されます。
[
{ XD_A: 'XDR', XD_B_1: '38', XD_B_2: 'PB' },
{ XD_A: 'XDR', XD_B_1: '38', XD_B_2: 'PB' }
]コードの仕組み
このコードでは、Array.prototype.filter() を使って各要素を順番にチェックしています。各オブジェクトに対して filters.forEach() で全ての条件を確認し、一つでも値が一致しないキーと値のペアがあれば throw で例外を発生させ、catch ブロックで false を返します。すべての条件が一致した場合のみ true を返し、そのオブジェクトが結果の配列に含まれるという仕組みです。
より簡潔な代替案:every() を活用する
try/catch による制御フローはやや複雑になりがちです。Array.prototype.every() を使えば、例外処理なしにより読みやすいコードで同じ動作を実現できます。
const filter = (data, filters) =>
data.filter(e =>
filters.every(o =>
Object.keys(o).every(key => e[key] === o[key])
)
);
console.info(filter(data, filters));外側の every() が「すべてのフィルター条件を満たしているか」を判定し、内側の every() が「その条件オブジェクトの全キーが一致しているか」を判定します。ネストされたループを明示的に書く必要がなく、意図がひと目で伝わるのが利点です。
-
JavaScriptでオブジェクトの配列を別の配列を使ってフィルタリングする方法
課題の概要まず、次のようなオブジェクトを要素にもつ配列が与えられたとします。const arr = [ {area: NY, name: Bla, ads: true}, {area: DF, name: SFS, ads: false}, {area: TT, name: SDSD, ads: true}, {area: SD, name: Engine, ads: false}, {area: NSK, name: Toyota, ads: false}, ];今回求められるのは、第1引数にこのようなオブジェクトの配列を、第2引数に文字列リテラルの配
-
JavaScriptでネストされた配列をフィルタリングする方法
この記事では、入れ子(ネスト)構造を持つオブジェクトの配列に対して、特定の条件に一致する要素だけを抽出するフィルター処理を、JavaScriptで実装する方法を解説します。Array.prototype.filter と Array.prototype.some を組み合わせることで、階層化されたデータも簡潔に検索できます。 問題の概要 まず、次のように legs という配列プロパティを持つオブジェクトの配列を想定します。 const arr = [{ id: 1, legs:[{ carrierName:Pegasus }] }, { id: