# 機能設計書 60-filter_nulls

## 概要

本ドキュメントは、Hack Standard Library (HSL) の `Vec\filter_nulls` 関数の機能設計書である。この関数はTraversableからnull以外の値のみを含む新しいvecを返す。型レベルでnullを除去するため、型安全性を提供する。

### 本機能の処理概要

**業務上の目的・背景**：
nullを含む可能性のあるコレクション（`Traversable<?Tv>`）から、null値を除去して非null値のみのコレクション（`vec<Tv>`）を得たい場合は頻繁にある。例えば、データベースからのnull許容フィールドの取得結果、オプショナルな値のマッピング結果、外部APIからのレスポンスなどが該当する。`Vec\filter_nulls` 関数は、このnull除去を型安全に行い、結果の型から自動的にnull可能性を除去する。

**機能の利用シーン**：
- データベースクエリ結果からのnull除去
- オプショナル値のコレクションの正規化
- 外部APIレスポンスのnullフィルタリング
- マッピング処理結果からの失敗（null）除去
- 部分的に欠損したデータのクリーニング

**主要な処理内容**：
1. Traversable（null許容型の要素を持つ）を受け取る
2. 各要素を走査
3. nullでない要素のみを結果vecに追加
4. 結果をvec<Tv>（非null型）として返却

**関連システム・外部連携**：
本関数は純粋な集合操作であり、外部システムとの直接的な連携はない。一般的なフィルタリングには `Vec\filter` を使用する。

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

## 関連画面

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

## 機能種別

フィルタリング処理 / 型変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | Traversable<?Tv> | Yes | 処理対象のコレクション（null許容型の要素） | null許容型の要素を持つTraversable |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | vec<Tv> | null以外の要素のみを含むvec（型からnullが除去される） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 変数初期化
   └─ 結果vecを空で初期化
2. コレクション走査
   └─ foreach で各要素を順番に処理
3. null判定
   └─ 要素が null でないことを厳密等価（!==）で確認
4. 要素追加
   └─ nullでない要素のみを結果vecに追加
5. 結果返却
   └─ 結果vecを返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[入力: $traversable]
    B --> C[result = vec 初期化]
    C --> D{次の要素あり?}
    D -->|No| G[結果を返却]
    D -->|Yes| E{$value !== null ?}
    E -->|Yes| F[result に要素を追加]
    E -->|No| D
    F --> D
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-60-01 | 厳密null判定 | `!== null` による厳密等価でnullを判定（falsy値は保持） | 常時 |
| BR-60-02 | 順序保持 | 結果の要素の順序は元のコレクションと同じ | 常時 |
| BR-60-03 | 型変換 | 戻り値の型は `vec<Tv>` であり、nullが型レベルで除去される | 常時 |
| BR-60-04 | falsy値保持 | false, 0, "", [] などのfalsy値はnullではないため保持される | 常時 |

### filter との違い

| 関数 | 除去される値 | 型変換 |
|------|-------------|--------|
| `Vec\filter()` | falsy値全般（0, "", false, null, []など） | なし |
| `Vec\filter_nulls()` | nullのみ | `?Tv` から `Tv` へ |

### 計算ロジック

- 計算量: O(n) - nは要素数
- 空間計算量: O(n) - 最大で全要素を含む可能性

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数は例外をスローしない | - |

### リトライ仕様

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

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

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

## パフォーマンス要件

- 計算量: O(n) - 全要素を1回走査
- 純粋関数 `[]` として定義されており、副作用なし
- メモリ効率: 結果のサイズ分のみ確保

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

- 入力データの検証は呼び出し側の責任
- null除去後のデータが適切に処理されることを確認

## 備考

- 一般的なフィルタリングには `Vec\filter()` を使用
- この関数は型チェッカーに対してnullが除去されたことを伝える
- `Vec\filter($vec, $x ==> $x !== null)` と同等だが、型安全性が向上

---

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

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

### 推奨読解順序

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

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

**読解のコツ**:
- 入力: `Traversable<?Tv>` - null許容型の要素を持つTraversable
- 出力: `vec<Tv>` - 非null型の要素を持つvec
- この型変換がfilter_nullsの主要な特徴

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

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

**主要処理フロー**:
1. **129行目**: 関数定義 `function filter_nulls<Tv>(Traversable<?Tv> $traversable)[]: vec<Tv>`
2. **130行目**: 結果vec を空で初期化
3. **131-135行目**: foreach ループで各要素を処理
4. **132-134行目**: `!== null` でnull判定し、非null要素のみ追加
5. **136行目**: 結果vecを返却

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | VecSelectTest.php | `tests/vec/VecSelectTest.php` | filter_nulls テスト（176-217行目） |

**主要ポイント**:
- **178-180行目**: 全nullの場合は空vecを返す
- **181-189行目**: false, "", 0 はnullではないので保持される
- **190-199行目**: nullと非null値が混在するケース

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

```
Vec\filter_nulls($traversable)
    │
    └─ foreach ($traversable as $value)  // 要素走査
           │
           └─ if ($value !== null)  // 厳密null判定
                  │
                  └─ $result[] = $value  // 要素追加
```

### データフロー図

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

$traversable ───────────────▶
 (Traversable<?Tv>)            Vec\filter_nulls ────▶ vec<Tv>
                                    │                (非null値のみ)
                                    │
                                    ▼
                               foreach loop
                                    │
                                    ├─ value !== null: keep
                                    │
                                    └─ value === null: skip
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.php | `src/vec/select.php` | ソース | filter_nulls関数のパブリックインターフェース |
| VecSelectTest.php | `tests/vec/VecSelectTest.php` | テスト | filter_nulls関数のユニットテスト |
