Arrayのfilterでデータを絞り込む
TypeScriptのArrayインスタンスのメソッドであるfilterを利用してデータを絞りこむプログラムに挑戦してみました!
今回はフィルタリングする検索条件を定義しており、filterメソッドで、各データに対して検索条件に該当するデータを絞り込みます。
また、everyメソッドを使い、すべての条件を満たすかどうかもチェックしています。
Sample.vue
■ SearchCondition型は検索条件を格納するクラスです。
・key: 検索対象のプロパティ名
・value: 検索する値。文字列または数値または真偽(true・false)を指定します
・matchType: 検索方法を指定する定数です
・1: 前方一致
・2: 完全一致
・3: 部分一致
・4: 範囲検索
・5: 真偽
・range: 範囲検索の場合に使用するオプションプロパティで、minとmaxを指定します。
■ searchConditionsは検索条件を配列で定義しています。ここで指定した条件でデータを検索することになります。
■ フィルタリングロジック
filterメソッドで、指定した検索条件を満たすデータを検索し、
everyメソッドを使用して全ての条件を満たしているかをチェックします。
<template>
<div>
<table>
<tbody>
<tr v-for="(item, index) in filteredItems" :key="index">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
<td>{{ item.city }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup lang="ts">
type Item = {
[key: string]: string | number | boolean | undefined;
};
// サンプルデータ
const items: Array<Item> = [
{ id: 1, name: "Alice", age: 25, city: "Okinawa", disp: false },
{ id: 2, name: "Taro", age: 33, city: "Osaka", disp: false },
{ id: 3, name: "Ponkotsu", age: 35, city: "Fukuoka", disp: false },
{ id: 4, name: "Hanako", age: 40, city: "Tokyo", disp: false },
{ id: 5, name: "Latte", age: 21, city: "Nagoya", disp: false },
{ id: 6, name: "Honey", age: "", city: "", disp: true },
];
// 検索条件の型
type SearchCondition = {
key: string;
value: string | number | boolean;
matchType: 1 | 2 | 3 | 4 | 5;
range?: { min: number; max: number };
disp?: boolean
};
// 検索条件の定義
const searchConditions: SearchCondition[] = [
{ key: "name", value: "A", matchType: 1, range: undefined, disp: true }, // 前方一致
{ key: "city", value: "Tokyo", matchType: 2, range: undefined, disp: undefined }, // 完全一致
{ key: "name", value: "kot", matchType: 3, range: undefined, disp: undefined }, // 部分一致
{ key: "age", matchType: 4, value: "", range: { min: 20, max: 30 }, disp: undefined }, // 範囲検索
{ key: "disp", matchType: 5, value: true, range: undefined, disp: undefined } , // 真偽
];
// フィルタリング関数 (OR検索)
const filteredItems = items.filter((item) =>
searchConditions.some((condition) => {
const itemValue = item[condition.key];
switch (condition.matchType) {
case 1: // 前方一致
return (
typeof itemValue === "string" &&
itemValue.startsWith(condition.value as string)
);
case 2: // 完全一致
return itemValue === condition.value;
case 3: // 部分一致
return (
typeof itemValue === "string" &&
itemValue.includes(condition.value as string)
);
case 4: // 範囲検索
if (typeof itemValue === "number" && condition.range) {
return (
itemValue >= condition.range.min &&
itemValue <= condition.range.max
);
}
case 5: // 真偽
return (
typeof itemValue === "boolean" &&
itemValue === condition.value
);
default:
return false;
}
})
);
</script>
以下が実行結果です。想定通りフィルタリングれました!
検索タイプごとの処理は以下の通りです。
・前方一致はitemValueが文字列型である場合にstartsWithを使用して前方一致を判定
・完全一致はitemValueが検索値condition.valueと一致するかを判定
・部分一致はitemValueが文字列型である場合にincludesを使用して部分一致を判定
・範囲検索はitemValueが数値型で、かつrangeプロパティが定義されている場合に、範囲内かを判定
・真偽はitemValueが真偽型で検索値condition.valueと一致するかを判定
今回のサンプルプログラムは柔軟な条件指定ができて、各matchTypeに応じたロジックを拡張できるのでfilterを試してみるのにちょうど良いかもしれません。
どうでしょう?今回のfilterを頑張ってマスターできそうですか?
難しいと思ったら、いろいろ自分で試してみて少しずつ理解を深めてみてくださいね!