# 機能設計書 83-filter

## 概要

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

### 本機能の処理概要

**業務上の目的・背景**：データ処理において、特定の条件を満たす要素のみを抽出するフィルタリング処理は最も基本的かつ頻繁に使用される操作の一つである。例えば、有効なユーザーのみを抽出する、特定のステータスを持つ注文のみを処理する、閾値を超えるデータのみを分析対象とするなど、様々なビジネスロジックで必要とされる。本関数は、このようなフィルタリング処理を型安全かつ効率的に行うためのユーティリティを提供する。

**機能の利用シーン**：
- 条件に合致するデータのみを抽出する場合
- 無効なデータや不要なデータを除外する場合
- 述語関数を省略して、truthy な値のみを抽出する場合（デフォルト動作）
- データのサブセットを生成する場合

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

**関連システム・外部連携**：本関数は純粋な計算処理であり、外部システムとの連携はない。非同期版として `Dict\filter_async()` が存在する。

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

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

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

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

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{$value_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-83-01 | デフォルト述語 | 述語関数が省略された場合、bool キャストを使用 | $value_predicate が null |
| BR-83-02 | 元の順序保持 | 結果の dict は元の順序を保持する | 常時 |
| BR-83-03 | キーの保持 | フィルタを通過したエントリは元のキーを保持する | 常時 |
| BR-83-04 | 値のみ評価 | フィルタリングは値のみを評価し、キーは考慮しない | 常時 |

### 計算ロジック

フィルタリング処理:
- 結果 = { (k, v) | (k, v) in $traversable AND $value_predicate(v) == true }
- デフォルト述語: boolval(v) - 値を bool にキャストした結果

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

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

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

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

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

## パフォーマンス要件

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

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

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

## 備考

- null 値を型安全に除去する場合は `Dict\filter_nulls()` を使用すること
- 非同期の述語関数を使用する場合は `Dict\filter_async()` を使用すること
- キーも評価に含めたい場合は `Dict\filter_with_key()` を使用すること

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: `?(function(Tv)[_]: bool)` は null 許容の関数型。`[_]` は任意のコンテキストを受け入れることを示す。

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

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

**主要処理フロー**:
1. **79-82行目**: 関数シグネチャと型定義
2. **83行目**: null 合体演算子でデフォルト述語を設定（`??=`）
3. **84行目**: 結果 dict の初期化
4. **85-89行目**: foreach ループでフィルタリング処理
5. **90行目**: 結果を返却

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.php | `src/dict/select.php` | filter_with_key（103-114行目）- キーも評価する版 |
| 3-2 | select.php | `src/dict/select.php` | filter_keys（124-136行目）- キーのみ評価する版 |
| 3-3 | select.php | `src/dict/select.php` | filter_nulls（145-155行目）- null を除去する版 |

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

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

### データフロー図

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

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

$value_predicate ─────> 述語関数の適用
(function or null)
         |
         +-- null の場合: boolval をデフォルト使用
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.php | `src/dict/select.php` | ソース | filter 関数の実装 |
| private.php | `src/private.php` | ソース | boolval 関数の実装 |
| async.php | `src/dict/async.php` | ソース | filter_async 関数の実装（非同期版） |
| DictSelectTest.php | `tests/dict/DictSelectTest.php` | テスト | filter のユニットテスト（111-158行目、214-226行目） |
