6日目のゴールと今日やること
6日目のテーマは
「検索 × ソート × フィルタ一覧アプリを“読みやすく・直しやすく・拡張しやすい設計”に進化させる」
ことです。
ここまでであなたは、
- リアルタイム検索
- 昇順 / 降順ソート
- 複合条件フィルタ
- タグフィルタ(AND / OR)
- ページネーション
- デバウンス
- ハイライト表示
- 条件保存(localStorage)
- データ追加・削除
といった、実務レベルの一覧アプリの基礎をすでに作り上げています。
6日目は、これらを 「設計として整理する」 回です。
つまり、
map / filter / sort を“アプリ全体の型”として扱えるようにする
ことが目的です。
アプリ全体の構造を「3 層」で整理する
一覧アプリは、次の 3 層で考えると劇的に読みやすくなります。
データ処理層(最下層)
- applyKeywordFilter
- applyAgeFilter
- applyTagFilter
- applySort
- applyPagination
ここは map / filter / sort / slice の世界 です。
状態管理層(state)
- filters
- sortState
- pagination
アプリの“今”を表す情報がここに集まります。
UI 層(最上層)
- renderList
- updateSortButtons
- イベント処理(検索、ソート、タグ、ページ移動など)
UI は「表示にだけ責任を持つ」ようにします。
この 3 層構造を意識すると、
どこで何をしているかが一気に見通しやすくなります。
データ処理層を「小さな関数の組み合わせ」にする
applyFilters の完成形
function applyFilters() {
let result = [...users];
result = applyKeywordFilter(result);
result = applyAgeFilter(result);
result = applyTagFilter(result);
result = applySort(result);
result = applyPagination(result);
renderList(result);
updateSortButtons();
saveState();
}
JavaScript深掘りポイント
ここが 6 日目の最重要ポイントです。
- 巨大な関数ではなく、小さな関数の組み合わせ
- map / filter / sort / slice を順番に適用
- 非破壊操作(元の users を壊さない)
- 最後に UI と保存処理を呼ぶだけ
これが「中級者の一覧アプリの型」です。
各フィルタ関数を“読みやすい形”にする
キーワードフィルタ
function applyKeywordFilter(arr) {
if (!filters.keyword) return arr;
const lower = filters.keyword.toLowerCase();
return arr.filter(user =>
user.name.toLowerCase().includes(lower)
);
}
JavaScript年齢フィルタ
function applyAgeFilter(arr) {
let result = arr;
if (filters.minAge !== null) {
result = result.filter(user => user.age >= filters.minAge);
}
if (filters.maxAge !== null) {
result = result.filter(user => user.age <= filters.maxAge);
}
return result;
}
JavaScriptタグフィルタ(AND / OR)
function applyTagFilter(arr) {
if (filters.tags.length === 0) return arr;
if (filters.tagMode === "OR") {
return arr.filter(user =>
user.tags.some(tag => filters.tags.includes(tag))
);
}
return arr.filter(user =>
filters.tags.every(tag => user.tags.includes(tag))
);
}
JavaScriptソート
function applySort(arr) {
if (!sortState.key) return arr;
const key = sortState.key;
const order = sortState.order;
return [...arr].sort((a, b) => {
if (order === "asc") {
return a[key] > b[key] ? 1 : -1;
} else {
return a[key] < b[key] ? 1 : -1;
}
});
}
JavaScriptページネーション
function applyPagination(arr) {
const start = (pagination.page - 1) * pagination.perPage;
return arr.slice(start, start + pagination.perPage);
}
JavaScript深掘りポイント
- すべて非破壊(arr を壊さない)
- filter は「条件を増やすほど絞り込まれる」
- sort は「比較関数」で自由に並び替え
- slice は「配列の一部を切り出す」
これらを組み合わせるだけで、
実務レベルの一覧処理が作れます。
状態管理層を整理する(責務の分離)
filters(検索条件)
const filters = {
keyword: "",
minAge: null,
maxAge: null,
tags: [],
tagMode: "OR"
};
JavaScriptsortState(ソート条件)
const sortState = {
key: null,
order: "asc"
};
JavaScriptpagination(ページ情報)
const pagination = {
page: 1,
perPage: 3
};
JavaScript深掘りポイント
state を分割することで、
- 何がどこで使われているかが明確
- applyFilters が読みやすくなる
- 機能追加がしやすい
これが「中級者の設計」です。
UI 層を整理する(表示とイベントを分離)
renderList(表示にだけ責任を持つ)
function renderList(arr) {
if (!arr.length) {
listDiv.textContent = "該当するユーザーはいません。";
return;
}
let html = "";
arr.forEach(user => {
const name = highlight(user.name, filters.keyword);
html += `<p>${name}(${user.age}歳)</p>`;
});
listDiv.innerHTML = html;
}
JavaScriptupdateSortButtons(ソート状態を UI に反映)
function updateSortButtons() {
sortAge.textContent =
sortState.key === "age"
? `年齢 ${sortState.order === "asc" ? "▲" : "▼"}`
: "年齢 ▲▼";
sortName.textContent =
sortState.key === "name"
? `名前 ${sortState.order === "asc" ? "▲" : "▼"}`
: "名前 ▲▼";
}
JavaScript深掘りポイント
UI は「表示にだけ責任を持つ」
ロジックは「処理にだけ責任を持つ」
この分離ができると、
アプリが一気に読みやすくなります。
6日目のまとめ
今日あなたがやったことを整理すると、こうなります。
- 一覧アプリを「データ処理層・状態管理層・UI 層」に分割
- applyFilters を小さな関数の組み合わせに再構築
- map / filter / sort / slice を“型”として扱えるようになった
- state を filters / sortState / pagination に分割
- UI とロジックを完全に分離
- 非破壊操作を徹底して安全なコードにした
どれも中級者に必須のスキルです。
今日いちばん深く理解してほしいこと
6日目の本質は、
「一覧アプリは、map / filter / sort を“設計として扱う”ことで、読みやすく・直しやすく・拡張しやすくなる」
ということです。
検索
→ 年齢フィルタ
→ タグフィルタ
→ ソート
→ ページネーション
→ 表示
この流れを applyFilters にまとめ、
小さな関数の組み合わせにすることで、
アプリは“中級者の設計”に進化します。
7日目では、この一覧アプリを
中級編の完成形としてまとめる
回に入ります。
あなたのアプリが「本当に使えるツール」になる瞬間です。


