かたちワークス|無料の読解体験
検索結果は、
なぜこの順番?
小さな検索教材を使って、「どこを読めば、結果の理由が分かるか」をたどります。必要なのはこのページだけ。インストールも、端末への入力も不要です。
読み終える目印:点数の付け方、同点の並び方、まだ分からないことを、自分の言葉で説明できる。
1予想する
検索語は red atlas。下の3件は、どの順番で返るでしょう? まずは自分なりに予想してから、次の答えを開いてください。
| ID | 題名 | 本文 |
|---|---|---|
| r1 | red atlas | blue |
| r2 | blue atlas | red |
| r3 | red notes | blue atlas |
この画面は新しい検索を行いません。制作時に保存した例を読み解く体験です。
2答えと根拠を読む
答えと加点の内訳を開く
r1 → r2 → r3
| ID | red | atlas | 合計 |
|---|---|---|---|
| r1 | 題名:2点 | 題名:2点 | 4点 |
| r2 | 本文:1点 | 題名:2点 | 3点 |
| r3 | 題名:2点 | 本文:1点 | 3点 |
まず全語一致。redとatlasの両方が、題名か本文に含まれる行を残します。この例では3件とも条件を満たします。
次に加点。各語が題名にあれば2点、本文にあれば1点を加えます。同じ語が題名と本文の両方にあれば、両方を足して3点です。
最後に並べ替え。点数の高い順(降順)、同点ならIDの昇順。r2とr3は3点なので、r2が先になります。
REAの記録は「読む場所」を教える
保存済みの解析記録で、検索関数 rankShelf は search.mjs の4〜34行、表記をそろえる fold は2行と分かります。その場所からソースを読み、上の説明につなげます。
位置の特定は静的解析の記録。点数や順序の説明は、ソース読解・手計算と2026-10-27の既存単体確認を結んだものです。REAがこの画面で検索を実行した結果ではありません。
根拠のソースと、読む目印を開く
18行:検索語をそろえて重複を除く。25行:全語がそろうか判定。28〜29行:題名と本文を加点。32〜33行:点数順・ID順に並べる。下は実行しない、原文の表示です。
掲載コード:Copyright (c) 2026 かたちワークス/教材コードのMITライセンス。ページ全体の文章には適用されません。
// ShelfSearch 1.0.0 — book teaching material, created 2026-10-27. const fold = (text) => text.normalize("NFKC").toLowerCase(); export function rankShelf(rows, query) { if (!Array.isArray(rows) || typeof query !== "string") { throw new TypeError("rows must be an array; query must be a string"); } const ids = new Set(); for (const row of rows) { if (row === null || typeof row !== "object" || typeof row.id !== "string" || row.id.length === 0 || typeof row.title !== "string" || typeof row.body !== "string") { throw new TypeError("each row needs a nonempty id, title and body strings"); } if (ids.has(row.id)) throw new RangeError("duplicate id"); ids.add(row.id); } const words = [...new Set(fold(query).trim().split(/\s+/u).filter(Boolean))]; if (words.length === 0) return []; const result = []; for (const row of rows) { const title = fold(row.title); const body = fold(row.body); if (!words.every((word) => title.includes(word) || body.includes(word))) { continue; } const score = words.reduce((sum, word) => sum + (title.includes(word) ? 2 : 0) + (body.includes(word) ? 1 : 0), 0); result.push({ id: row.id, title: row.title, score }); } return result.sort((a, b) => b.score - a.score || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)); }
解析の範囲と記録を確認する
REA 6.8.0/ShelfSearch 1.0.0。2026-10-28の限定静的解析で選択したのは search.mjs 1ファイルです。構文解析の失敗0、結果量による省略なし。ただし網羅性は partial です。
「省略なし」は「全動作を証明済み」ではありません。実アプリの画面動作、未選択ファイルを通る関係、全関係、別実装との一致は未確認です。未知の市販アプリへ、この結果をそのまま広げられません。
Evidence IDev_ce801fc91b4e6b90f7deb172cc162231d8d181ec6948c8cc876e3296572fb102
来歴:制作時の records/REA680-ShelfSearch-search.json と完成メモの例。これは元記録の案内名です。このHTMLに解析JSON全体は収録していません。ソース原文のSHA-256は同梱の manifest.json に記録しています。
3自分で説明する
答えを開く前に、次の3つを自分の言葉で説明してみてください。自動採点や合格の記録はありません。
① なぜr1が最初になる?
redとatlasがどちらも題名にあり、2点+2点で4点。r2とr3の3点より高いためです。
② 同じ3点なのに、なぜr2がr3より先?
同点時はIDの昇順に並べる規則があるからです。この例のIDではr2がr3より先です。
③ partialでも「全動作を証明できた」と言える?
言えません。これは選んだソースの静的な記録です。画面の動作や未選択ファイルとの関係は残り、検索関数をこのページで実行してもいません。
説明できたら、次は手元の解析へ
ここでできたのは「保存済み記録の読解」です。自分で解析した経験とは分けて記録しましょう。本書5.1「最初の解析を、準備から説明まで通す」では、同じ教材を自分の環境で解析する手順へ進めます。