3日目のゴールと今日やること
3日目のテーマは
「検索 × ソート × フィルタを“実務レベル”で組み合わせて、より高度な一覧アプリを作る」
ことです。
1日目で map / filter / sort の基礎、
2日目で state を使った検索・ソート・フィルタの統合処理を学びました。
3日目では、さらに一歩進んで
- タグフィルタ(複数条件の AND / OR)
- ソート条件の切り替え(名前順・年齢順など)
- ページネーション(一覧を分割して表示)
- UI とロジックの分離をより強固にする
といった「実務でよく使う一覧機能」を作っていきます。
今日のキーワードは
「複数条件の組み合わせ」 と
「非破壊操作の徹底」
です。
タグフィルタを作る(複数条件 AND / OR)
例:ユーザーにタグを付ける
const users = [
{ id: 1, name: "Alice", age: 24, tags: ["frontend", "remote"] },
{ id: 2, name: "Bob", age: 30, tags: ["backend"] },
{ id: 3, name: "Charlie", age: 28, tags: ["frontend", "design"] },
{ id: 4, name: "David", age: 35, tags: ["remote"] },
{ id: 5, name: "Eve", age: 22, tags: ["design"] }
];
JavaScriptUI のイメージ
<label><input type="checkbox" class="tag" value="frontend" /> Frontend</label>
<label><input type="checkbox" class="tag" value="backend" /> Backend</label>
<label><input type="checkbox" class="tag" value="design" /> Design</label>
<label><input type="checkbox" class="tag" value="remote" /> Remote</label>
JavaScript 側で取得します。
const tagCheckboxes = document.querySelectorAll(".tag");
JavaScriptタグフィルタのロジック(AND / OR の違い)
OR 条件(どれか 1 つでも含む)
function filterByTagsOR(arr, selectedTags) {
if (selectedTags.length === 0) return arr;
return arr.filter(user =>
user.tags.some(tag => selectedTags.includes(tag))
);
}
JavaScriptAND 条件(すべて含む)
function filterByTagsAND(arr, selectedTags) {
if (selectedTags.length === 0) return arr;
return arr.filter(user =>
selectedTags.every(tag => user.tags.includes(tag))
);
}
JavaScript深掘りポイント
- some → OR 条件
- every → AND 条件
この 2 つを使い分けるだけで、
複雑なタグ検索が簡単に作れます。
state にタグフィルタを追加する
const state = {
keyword: "",
sort: "none",
minAge: null,
maxAge: null,
tags: [],
tagMode: "OR" // OR または AND
};
JavaScriptタグチェックボックスのイベントをつなぎます。
tagCheckboxes.forEach(cb => {
cb.addEventListener("change", () => {
const selected = [...tagCheckboxes]
.filter(c => c.checked)
.map(c => c.value);
updateState({ tags: selected });
});
});
JavaScriptapplyFilters にタグフィルタを統合する
function applyFilters() {
let result = [...users];
if (state.keyword) {
const lower = state.keyword.toLowerCase();
result = result.filter(user =>
user.name.toLowerCase().includes(lower)
);
}
if (state.minAge !== null) {
result = result.filter(user => user.age >= state.minAge);
}
if (state.maxAge !== null) {
result = result.filter(user => user.age <= state.maxAge);
}
if (state.tags.length > 0) {
if (state.tagMode === "OR") {
result = filterByTagsOR(result, state.tags);
} else {
result = filterByTagsAND(result, state.tags);
}
}
if (state.sort === "asc") {
result = [...result].sort((a, b) => a.age - b.age);
}
if (state.sort === "desc") {
result = [...result].sort((a, b) => b.age - a.age);
}
renderList(result);
}
JavaScript深掘りポイント
applyFilters が
検索 → 年齢 → タグ → ソート → 表示
という「処理の流れ」を完全に管理しています。
これが中級者のコードです。
ソート条件を増やす(名前順・年齢順)
state に sortKey を追加
const state = {
keyword: "",
sort: "none",
sortKey: "age", // "age" or "name"
minAge: null,
maxAge: null,
tags: [],
tagMode: "OR"
};
JavaScriptソートロジックを拡張
if (state.sort !== "none") {
const key = state.sortKey;
result = [...result].sort((a, b) => {
if (state.sort === "asc") {
return a[key] > b[key] ? 1 : -1;
} else {
return a[key] < b[key] ? 1 : -1;
}
});
}
JavaScript深掘りポイント
sortKey を変えるだけで
「名前順」「年齢順」などの切り替えが可能になります。
ページネーションを追加する(一覧を分割表示)
state にページ情報を追加
const state = {
...,
page: 1,
perPage: 3
};
JavaScriptページネーション処理
function paginate(arr, page, perPage) {
const start = (page - 1) * perPage;
return arr.slice(start, start + perPage);
}
JavaScriptapplyFilters の最後に追加
const paginated = paginate(result, state.page, state.perPage);
renderList(paginated);
JavaScript深掘りポイント
slice は非破壊なので、
元の配列を壊さずにページ分割できます。
ページボタンを UI とつなぐ
prevButton.addEventListener("click", () => {
if (state.page > 1) {
updateState({ page: state.page - 1 });
}
});
nextButton.addEventListener("click", () => {
updateState({ page: state.page + 1 });
});
JavaScript3日目のまとめ
今日あなたがやったことを整理すると、こうなります。
- タグフィルタ(OR / AND)を実装
- state にタグ情報を追加
- applyFilters にタグ処理を統合
- ソート条件を「名前順」「年齢順」に拡張
- ページネーションを追加
- UI とロジックを完全に分離
- filter / sort / slice を組み合わせて高度な一覧処理を実現
どれも実務で頻繁に使うテクニックです。
今日いちばん深く理解してほしいこと
3日目の本質は、
「検索・ソート・フィルタは、map / filter / sort / slice を組み合わせることで“無限に拡張できる”」
ということです。
タグ検索
複合条件
ページネーション
ソート切り替え
これらはすべて
高階関数の組み合わせ
で作れます。
4日目では、この一覧アプリに
- デバウンス(検索の負荷軽減)
- ハイライト表示
- ソートアイコンの切り替え
- 状態管理の整理(state の分割)
などを加えて、さらに“プロ仕様の一覧アプリ”に育てていきます。


