# 機能設計書 85-filter_keys

## 概要

本ドキュメントは、Hack Standard Library (HSL) の Dict モジュールにおける `filter_keys` 関数の機能設計を記述する。この関数は、述語関数がキーに対して true を返すエントリのみを含む新しい dict を返す機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：データ処理において、キーに基づいてエントリをフィルタリングしたいケースは多い。例えば、特定の接頭辞を持つキーのみを抽出する、数値キーの範囲でフィルタリングする、特定のパターンに一致するキーを選択するなどである。本関数は、このようなキーベースのフィルタリング処理を型安全に行うためのユーティリティを提供する。

**機能の利用シーン**：
- 特定の命名規則に従うキーのみを抽出する場合
- 数値キーの偶数・奇数でフィルタリングする場合
- キーの接頭辞や接尾辞に基づいてフィルタリングする場合
- 述語関数を省略して、truthy なキーのみを抽出する場合（デフォルト動作）

**主要な処理内容**：
1. 述語関数が省略された場合、デフォルトで boolval（bool キャスト）を使用
2. 入力の KeyedTraversable を順次イテレート
3. 各エントリのキーに対して述語関数を適用
4. 述語関数が true を返した場合のみ、結果の dict にエントリを追加
5. 結果の dict を返却

**関連システム・外部連携**：本関数は純粋な計算処理であり、外部システムとの連携はない。

**権限による制御**：本関数は汎用ユーティリティであり、権限による制御は行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | 本プロジェクトはUIを持たないライブラリのため画面なし |

## 機能種別

計算処理（フィルタリング）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | KeyedTraversable<Tk, Tv> | Yes | フィルタリング対象の KeyedTraversable | なし |
| $key_predicate | ?(function(Tk)[_]: bool) | No | キーを引数に取り、bool を返す述語関数。省略時は boolval を使用 | なし |

### 入力データソース

関数引数として直接渡される KeyedTraversable オブジェクトと述語関数。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | dict<Tk, Tv> | 述語関数がキーに対して true を返したエントリのみを含む dict |

### 出力先

関数の戻り値として呼び出し元に返却。

## 処理フロー

### 処理シーケンス

```
1. 述語関数の設定
   └─ $key_predicate が null の場合、boolval をデフォルトとして設定
2. 結果用の空 dict を初期化
3. $traversable を foreach でイテレート
   ├─ 各エントリのキーに対して述語関数を適用
   └─ true の場合、結果 dict にエントリを追加
4. 結果の dict を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{$key_predicate は null か?}
    B -->|Yes| C[boolval をデフォルトとして設定]
    B -->|No| D[指定された述語を使用]
    C --> E[result = dict[]]
    D --> E
    E --> F{次のエントリがあるか?}
    F -->|No| G[result を返却]
    F -->|Yes| H[述語関数をキーに適用]
    H --> I{結果は true か?}
    I -->|Yes| J[result にエントリを追加]
    I -->|No| F
    J --> F
    G --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-85-01 | デフォルト述語 | 述語関数が省略された場合、bool キャストを使用 | $key_predicate が null |
| BR-85-02 | キーのみ評価 | フィルタリングはキーのみを評価し、値は考慮しない | 常時 |
| BR-85-03 | 元の順序保持 | 結果の dict は元の順序を保持する | 常時 |
| BR-85-04 | 元の値保持 | フィルタを通過したエントリは元のキーと値を保持する | 常時 |

### 計算ロジック

フィルタリング処理:
- 結果 = { (k, v) | (k, v) in $traversable AND $key_predicate(k) == true }
- デフォルト述語: boolval(k) - キーを bool にキャストした結果
  - 空文字列 '' と '0' と 0 は false
  - それ以外は true

## データベース操作仕様

### 操作別データベース影響一覧

本関数はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 型エラー | 不正な型の引数が渡された場合 | Hack型システムによりコンパイル時に検出 |

### リトライ仕様

本関数は純粋関数であり、リトライの概念は適用されない。

## トランザクション仕様

本関数はステートレスな純粋関数であり、トランザクション管理は不要。

## パフォーマンス要件

- 時間計算量: O(n * p)、n は $traversable のサイズ、p は述語関数の計算量（省略時は O(1)）
- 空間計算量: O(n)

## セキュリティ考慮事項

- 純粋関数であり、副作用がないためセキュリティリスクは低い
- 述語関数のコンテキスト（ctx）が伝播されるため、述語関数の副作用も追跡可能

## 備考

- 値でフィルタリングする場合は `Dict\filter()` を使用すること
- キーと値の両方でフィルタリングする場合は `Dict\filter_with_key()` を使用すること
- 特定のキーセットでフィルタリングする場合は `Dict\select_keys()` の方が効率的

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | select.php | `src/dict/select.php` | filter_keys 関数のシグネチャと型パラメータ |
| 1-2 | private.php | `src/private.php` | boolval 関数の実装（49-51行目） |

**読解のコツ**: `?(function(Tk)[_]: bool)` は null 許容の関数型。キーの型 Tk は arraykey（int または string）の制約がある。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | select.php | `src/dict/select.php` | filter_keys 関数の実装（124-136行目） |

**主要処理フロー**:
1. **124-127行目**: 関数シグネチャと型定義
2. **128行目**: null 合体演算子でデフォルト述語を設定
3. **129行目**: 結果 dict の初期化
4. **130-134行目**: foreach ループでフィルタリング処理
5. **135行目**: 結果を返却

#### Step 3: 関連関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.php | `src/dict/select.php` | filter（79-91行目）- 値でフィルタ |
| 3-2 | select.php | `src/dict/select.php` | filter_with_key（103-114行目）- キーと値でフィルタ |
| 3-3 | select.php | `src/dict/select.php` | select_keys（165-178行目）- 指定キーで選択 |

### プログラム呼び出し階層図

```
Dict\filter_keys($traversable, $key_predicate)
    |
    +-- $key_predicate ?? boolval<>  [デフォルト述語の設定]
    |
    +-- foreach ($traversable as $key => $value)
            |
            +-- $key_predicate($key)  [述語の適用]
            |
            +-- $dict[$key] = $value  [条件付きで追加]
```

### データフロー図

```
[入力]                      [処理]                           [出力]

$traversable ──────────> foreach ループ ─────────────────> dict<Tk, Tv>
(KeyedTraversable)           |
                             +-- 各キーに述語を適用
                             |
                             +-- true: 結果に追加
                             +-- false: スキップ

$key_predicate ───────> 述語関数の適用
(function or null)          |
         |                  +-- null の場合: boolval をデフォルト使用
         +-- キーのみを評価（値は無視）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.php | `src/dict/select.php` | ソース | filter_keys 関数の実装 |
| private.php | `src/private.php` | ソース | boolval 関数の実装 |
| DictSelectTest.php | `tests/dict/DictSelectTest.php` | テスト | filter_keys のユニットテスト（228-276行目） |
