# 機能設計書 59-filter

## 概要

本ドキュメントは、Hack Standard Library (HSL) の `Vec\filter` 関数の機能設計書である。この関数は述語関数（predicate）がtrueを返す要素のみを含む新しいvecを返す。

### 本機能の処理概要

**業務上の目的・背景**：
データ処理において、特定の条件を満たす要素のみを抽出するフィルタリング処理は最も基本的かつ頻繁に使用される操作の一つである。例えば、アクティブなユーザーのみを抽出、特定の価格帯の商品を選択、有効なレコードのみを処理するなど、様々な場面で必要とされる。`Vec\filter` 関数は、任意の条件でコレクションをフィルタリングする汎用的な方法を提供する。

**機能の利用シーン**：
- 条件に基づくデータの抽出
- 無効なデータの除外
- 検索条件によるフィルタリング
- 特定のステータスを持つ要素の選択
- 数値範囲によるフィルタリング
- 複合条件での絞り込み

**主要な処理内容**：
1. Traversable（反復可能なコレクション）を受け取る
2. 述語関数（オプション）を受け取る
3. 各要素に対して述語関数を適用
4. trueを返した要素のみを結果vecに追加
5. 結果をvecとして返却

**関連システム・外部連携**：
内部実装ではデフォルト述語として `_Private\boolval` を使用する。null値の除去には `Vec\filter_nulls` を使用する。非同期述語には `Vec\filter_async` を使用する。

**権限による制御**：
本機能は純粋関数であり、権限による制御は存在しない。

## 関連画面

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

## 機能種別

フィルタリング処理 / データ選択

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | Traversable<Tv> | Yes | 処理対象のコレクション | 任意の型の要素を持つTraversable |
| $value_predicate | ?(function(Tv)[_]: bool) | No | 要素をフィルタリングする述語関数（デフォルト: boolval変換） | boolを返す関数 |

### 入力データソース

関数呼び出し時の引数として直接渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | vec<Tv> | 述語がtrueを返した要素のみを含むvec |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 述語関数の決定
   └─ $value_predicate が null の場合、_Private\boolval を使用
2. 変数初期化
   └─ 結果vecを空で初期化
3. コレクション走査
   └─ foreach で各要素を順番に処理
4. 述語適用
   └─ 各要素に対して述語関数を適用
5. 条件判定
   └─ 述語がtrueを返した場合のみ結果vecに追加
6. 結果返却
   └─ 結果vecを返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[入力: $traversable, $value_predicate]
    B --> C{$value_predicate は null?}
    C -->|Yes| D[$value_predicate = _Private\boolval]
    C -->|No| E[指定された述語を使用]
    D --> F[result = vec 初期化]
    E --> F
    F --> G{次の要素あり?}
    G -->|No| J[結果を返却]
    G -->|Yes| H{$value_predicate が true?}
    H -->|Yes| I[result に要素を追加]
    H -->|No| G
    I --> G
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-59-01 | デフォルト述語 | 述語が指定されない場合、boolval変換（真偽値への変換）が使用される | $value_predicate が null の場合 |
| BR-59-02 | 順序保持 | 結果の要素の順序は元のコレクションと同じ | 常時 |
| BR-59-03 | 全除外 | 全ての要素が述語でfalseの場合、空のvecを返す | 常時 |
| BR-59-04 | 全保持 | 全ての要素が述語でtrueの場合、全要素を含むvecを返す | 常時 |

### デフォルト述語の動作

デフォルトの `boolval` 変換では、以下の値がfalse（除外）と判定される：
- `false`
- `0` （整数）
- `0.0` （浮動小数点）
- `""` （空文字列）
- `"0"` （文字列の"0"）
- `null`
- 空の配列/vec

### 計算ロジック

- 計算量: O(n * p) - nは要素数、pは述語関数の計算量
- 空間計算量: O(n) - 最大で全要素を含む可能性

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

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

本機能はデータベース操作を行わない純粋関数である。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数は例外をスローしない（述語関数が例外をスローする可能性あり） | - |

### リトライ仕様

リトライは不要（同期的な純粋関数のため）

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

該当なし（データベース操作を行わないため）

## パフォーマンス要件

- 計算量: O(n * p) - 述語関数の計算量に依存
- 純粋関数として定義（ctx $value_predicateにより関数の副作用を継承）
- メモリ効率: 結果のサイズ分のみ確保

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

- 述語関数は信頼できるコードから提供されるべき
- フィルタリング条件が機密情報に基づく場合は結果の取り扱いに注意

## 備考

- null値の除去には型安全な `Vec\filter_nulls()` を使用することを推奨
- 非同期述語が必要な場合は `Vec\filter_async()` を使用
- キーも使用したい場合は `Vec\filter_with_key()` を使用
- `ctx $value_predicate` により、述語関数の副作用コンテキストを継承

---

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

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

### 推奨読解順序

#### Step 1: 関数シグネチャを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | select.php | `src/vec/select.php` | 関数シグネチャと型パラメータ（108-111行目） |

**読解のコツ**:
- `?(function(Tv)[_]: bool)` は null許容の関数型
- `[_]` はコンテキスト変数（副作用の伝播）
- `ctx $value_predicate` で述語のコンテキストを継承

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

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

**主要処理フロー**:
1. **112行目**: null合体演算子でデフォルト述語を設定 `$value_predicate ??= _Private\boolval<>`
2. **113行目**: 結果vec を空で初期化
3. **114-118行目**: foreach ループで各要素を処理
4. **115-117行目**: 述語がtrueなら要素を追加
5. **119行目**: 結果vecを返却

#### Step 3: デフォルト述語を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | private.php | `src/private.php` | boolval関数の実装（49-51行目） |

**主要ポイント**:
- 単純に `(bool)$val` でキャストを行う

#### Step 4: テストケースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | VecSelectTest.php | `tests/vec/VecSelectTest.php` | filter テスト（126-174行目） |

**主要ポイント**:
- **144-146行目**: 偶数のみを抽出する例
- **170-173行目**: デフォルト述語（boolval）のテスト

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

```
Vec\filter($traversable, $value_predicate)
    │
    ├─ $value_predicate ??= _Private\boolval<>  // デフォルト述語
    │
    └─ foreach ($traversable as $value)  // 要素走査
           │
           └─ if ($value_predicate($value))  // 述語適用
                  │
                  └─ $result[] = $value  // 要素追加
```

### データフロー図

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

$traversable ───────────────▶
 (Traversable<Tv>)             Vec\filter ──────────▶ vec<Tv>
                                    │               (述語がtrueの要素)
$value_predicate ───────────▶       │
 (function or null)                 │
                                    ▼
                               foreach loop
                                    │
                                    ├─ predicate(value) == true: keep
                                    │
                                    └─ predicate(value) == false: skip
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.php | `src/vec/select.php` | ソース | filter関数のパブリックインターフェース |
| private.php | `src/private.php` | ソース | boolvalデフォルト述語 |
| async.php | `src/vec/async.php` | ソース | filter_async（非同期版） |
| VecSelectTest.php | `tests/vec/VecSelectTest.php` | テスト | filter関数のユニットテスト |
