# 機能設計書 139-min_by

## 概要

本ドキュメントは、Hack Standard Library (HSL) の Math 名前空間における `min_by` 関数の機能設計書である。この関数は、与えられた Traversable（走査可能なコレクション）から、スカラー関数によって計算された数値が最小となる要素を取得して返す。

### 本機能の処理概要

**業務上の目的・背景**：
実際のアプリケーションでは、数値コレクションの最小値ではなく、オブジェクトの特定のプロパティに基づいて最小要素を取得したいケースが多い。例えば、ユーザーリストから最低スコアのユーザーを取得したり、商品リストから最低価格の商品を取得したりする場合である。`Math\min_by` 関数は、このような要件に対応するため、比較に使用する数値を計算するための関数を引数として受け取り、その数値が最小となる要素を返す。

**機能の利用シーン**：
- ユーザーリストから最低スコアのユーザーを取得
- 商品リストから最低価格の商品を取得
- 文字列リストから最短の文字列を取得
- レコードリストから最古の日付のレコードを取得
- オブジェクトの複合条件での最小値探索

**主要な処理内容**：
1. Traversable<T> 型のコレクションとスカラー関数を受け取る
2. コレクションを走査し、各要素に対してスカラー関数を適用する
3. スカラー関数の戻り値が最小となる要素を追跡する
4. コレクションが空の場合は null を返し、そうでなければ最小要素を返す

**関連システム・外部連携**：
本機能はコレクション操作関数であり、外部システムとの連携はない。

**権限による制御**：
本機能は高階関数として実装されており、渡されるスカラー関数のコンテキストを継承する。純粋関数として使用する場合は純粋なスカラー関数を渡す必要がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本プロジェクト（Hack Standard Library）はUIを持たないライブラリプロジェクトのため、画面機能マッピングは該当しない |

## 機能種別

計算処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | Traversable<T> | Yes | 最小要素を求めるコレクション | なし |
| $num_func | (function(T)[_]: num) | Yes | 各要素から比較用の数値を計算する関数 | なし |

### 入力データソース

関数呼び出し時の引数として直接指定される。任意の型 T のコレクションと、T から num への変換関数が使用可能。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (戻り値) | ?T | スカラー関数の戻り値が最小となる要素、または空の場合は null |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 引数 $traversable と $num_func を受け取る
   └─ $traversable: Traversable<T>、$num_func: (function(T)[_]: num)
2. 最小値変数と最小数値変数を null で初期化
   └─ $min = null、$min_num = null
3. コレクションを走査
   └─ foreach ($traversable as $value)
4. 各要素に対してスカラー関数を適用
   └─ $value_num = $num_func($value)
5. 比較と更新
   ├─ $min_num が null、または $value_num <= $min_num の場合
   └─ $min = $value、$min_num = $value_num に更新
6. 最小要素を返す
   └─ 空のコレクションの場合は null
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B["$min = null, $min_num = null"]
    B --> C{$traversable に要素あり?}
    C -->|No| H[null を返す]
    C -->|Yes| D[次の $value を取得]
    D --> E["$value_num = $num_func($value)"]
    E --> F{"$min_num === null または $value_num <= $min_num?"}
    F -->|Yes| G["$min = $value, $min_num = $value_num"]
    F -->|No| C
    G --> C
    C -->|走査完了| I["$min を返す"]
    H --> J[終了]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 空コレクション | 空のコレクションに対しては null を返す | $traversable が空の場合 |
| BR-002 | 同値の処理 | 同じ数値の場合、後の要素が優先される（<= 比較） | 常に適用 |
| BR-003 | 型保持 | 戻り値の型は入力要素の型 T と同じ | 常に適用 |
| BR-004 | コンテキスト継承 | 関数のコンテキストはスカラー関数のコンテキストに依存 | 常に適用 |

### 計算ロジック

線形走査による最小値探索：
- 時間計算量: O(n) - n は要素数
- 空間計算量: O(1) - 追加のメモリ使用は定数
- スカラー関数は各要素に対して1回だけ呼び出される

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 本関数自体はエラーをスローしない | - |
| - | 任意 | スカラー関数内でエラーが発生した場合 | スカラー関数の実装を確認 |

### リトライ仕様

該当なし

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

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

## パフォーマンス要件

コレクションを一度だけ走査するため、時間計算量は O(n) である。スカラー関数の呼び出し回数も n 回であり、スカラー関数の計算量がパフォーマンスに影響する。

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

渡されるスカラー関数の実装に依存する。スカラー関数が副作用を持つ場合、その影響を考慮する必要がある。

## 備考

- 数値コレクションの最小値を求める場合は `Math\min` 関数を使用する方がシンプル
- 最大値を求める場合は `Math\max_by` 関数を使用する
- 同じ数値を持つ複数の要素がある場合、後の要素が返される（<= 比較のため）

---

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

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

### 推奨読解順序

#### Step 1: min_by 関数の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | containers.php | `src/math/containers.php` | min_by 関数の実装（116-139行目）を確認。スカラー関数を使用した最小値探索アルゴリズムを理解する |

**主要処理フロー**:
1. **116-124行目**: 関数のドキュメントコメント - min 関数への参照と重複キーの処理について説明
2. **125-128行目**: 関数シグネチャ - コンテキスト係数 `[ctx $num_func]` の使用に注目
3. **129-130行目**: 最小値と最小数値の初期化
4. **131-137行目**: foreach による走査、スカラー関数の適用、比較ロジック（<= 比較）
5. **138行目**: 結果を返す

**読解のコツ**: `[ctx $num_func]` は Hack のコンテキスト機能で、関数のコンテキスト（純粋性など）がスカラー関数のコンテキストに依存することを示す。max_by との違いは比較演算子のみ（>= vs <=）。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | containers.php | `src/math/containers.php` | min 関数（104-114行目）の実装を比較。数値専用版との違いを理解する |
| 2-2 | containers.php | `src/math/containers.php` | max_by 関数（42-56行目）の実装を比較。対称的な実装であることを確認 |

#### Step 3: テストケースを確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MathContainersTest.php | `tests/math/MathContainersTest.php` | provideTestMinBy メソッド（153-173行目）とtestMinBy メソッド（175-182行目）を確認 |

**主要処理フロー**:
- **154-159行目**: 空の vec に対するテスト - null が返される
- **160-165行目**: 文字列の長さによる最小値 - 'fox' が返される（最短文字列）
- **166-172行目**: Iterator に対するテスト - 同様に 'fox' が返される

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

```
Math\min_by($traversable, $num_func)
    │
    ├─ $min = null, $min_num = null の初期化
    │
    └─ foreach ($traversable as $value)
           │
           ├─ $value_num = $num_func($value)
           │
           └─ if ($min_num === null || $value_num <= $min_num)
                  └─ $min = $value, $min_num = $value_num
```

### データフロー図

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

Traversable<T> ─────────┐
      $traversable      │
                        ▼
                   foreach で走査
                        │
(function(T): num) ─────┼───▶ $num_func($value) ───▶ ?T 最小要素
      $num_func         │                             または null
                        ▼
                   各要素の数値を比較
                   最小要素を更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| containers.php | `src/math/containers.php` | ソース | min_by 関数の実装ファイル（コレクション操作関数群） |
| MathContainersTest.php | `tests/math/MathContainersTest.php` | テスト | min_by 関数を含むコレクション関数のユニットテスト |
