# 機能設計書 107-find_key

## 概要

本ドキュメントは、Hack Standard Library（HSL）の `C\find_key` 関数の機能設計書である。この関数は、KeyedTraversableの中から述語を満たす最初の値のキーを取得する。

### 本機能の処理概要

`C\find_key` 関数は、与えられた `KeyedTraversable` の要素を順番に調べ、指定された述語関数が `true` を返す最初の要素の**キー**を返す関数である。条件を満たす要素が見つからない場合は `null` を返す。

**業務上の目的・背景**：コレクション内から特定の条件を満たす要素を検索し、その要素自体ではなくキー（インデックスや辞書キー）が必要な場合に使用される。例えば、特定の条件を満たす要素の位置を知りたい場合や、後でそのキーを使って別の操作（更新や削除）を行いたい場合に有用である。`C\find` が値を返すのに対し、本関数はキーを返す点が異なる。

**機能の利用シーン**：
- 配列内で特定の値を持つ要素のインデックスを取得する場合
- 辞書型データで条件を満たす要素のキーを取得し、後で更新する場合
- リスト内の特定要素の位置を特定する場合
- 検索結果のキーを使って関連データを取得する場合
- 条件に合致する要素を削除するためにキーを取得する場合

**主要な処理内容**：
1. 入力パラメータとして KeyedTraversable と述語関数を受け取る
2. KeyedTraversable の各要素に対してループ処理
3. 各要素に述語を適用
4. 述語が true を返す最初の要素のキーを返す（ショートサーキット）
5. 条件を満たす要素がない場合は null を返す

**関連システム・外部連携**：なし（純粋な関数であり、外部システムへの依存はない）

**権限による制御**：なし（ライブラリ関数のため権限制御は不要）

## 関連画面

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

## 機能種別

検索処理 / 選択処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | KeyedTraversable<Tk, Tv> | Yes | 検索対象のKeyedTraversable | なし |
| $value_predicate | (function(Tv)[_]: bool) | Yes | 各要素の値に適用する述語関数 | bool を返す必要あり |

### 入力データソース

関数呼び出し元から引数として渡される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | ?Tk | 条件を満たす最初の値のキー。見つからない場合は `null` |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. KeyedTraversable と述語関数を引数として受け取る
   └─ 述語は必須パラメータ
2. KeyedTraversable の各要素に対してループ処理
   └─ foreach ($traversable as $key => $value) で順次処理
3. 各要素の値に述語を適用
   └─ 述語が true を返した場合、そのキーを即座に返す（ショートサーキット）
4. ループが終了しても条件を満たす要素がない場合
   └─ null を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[traversable, predicate を受け取る]
    B --> C[foreach ループ開始]
    C --> D{次の要素あり?}
    D -->|Yes| E[値に predicate を適用]
    E --> F{結果が true?}
    F -->|Yes| G[そのキーを返す]
    F -->|No| C
    D -->|No| H[null を返す]
    G --> I[終了]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-107-01 | 最初の一致キーを返す | 複数の要素が条件を満たす場合、最初に見つかった要素のキーのみを返す | 常に適用 |
| BR-107-02 | ショートサーキット | 条件を満たす要素が見つかった時点で処理を終了 | 要素が条件を満たした場合 |
| BR-107-03 | null許容戻り値 | 条件を満たす要素がない場合は null を返す | 要素が見つからない場合 |
| BR-107-04 | 値で検索しキーを返す | 述語は値に適用されるが、戻り値はキーである | 常に適用 |

### 計算ロジック

特になし（検索処理のみで複雑な計算処理は含まれない）

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

該当なし（本機能はインメモリのコレクション操作のみを行う）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TypeError | 型エラー | 述語が bool を返さない場合 | 型チェッカーがコンパイル時に検出 |

### リトライ仕様

該当なし（同期処理であり、リトライの必要性はない）

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

該当なし（データベース操作を行わない純粋関数）

## パフォーマンス要件

- 時間計算量: O(n) - 最悪の場合、全要素をチェック
- 空間計算量: O(1)
- ショートサーキット評価により、条件を満たす要素が見つかった時点で処理終了

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

- 純粋関数であり、外部への副作用がないためセキュリティリスクは低い
- 述語関数は呼び出し元から渡されるため、述語内での副作用には注意が必要

## 備考

- `C\find` は値を返すが、本関数はキーを返す
- vec の場合、キーは 0 始まりのインデックス（int）となる
- dict の場合、キーは string または int となる
- 関連関数: `C\find`（値取得版）、`C\findx`（必須版）

---

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

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

### 推奨読解順序

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

本関数で扱うデータ構造は、Hack言語の組み込み型である `KeyedTraversable` である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | (Hack組み込み型) | - | KeyedTraversable<Tk, Tv> は キーと値のペアで反復可能な型の基底インターフェース |

**読解のコツ**: `KeyedTraversable` は `Traversable` を拡張し、キーへのアクセスを可能にする。戻り値の `?Tk` はキーの型が null 許容であることを示す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | select.php | `src/c/select.php` | C\find_key 関数の定義を確認 |

**主要処理フロー**:
1. **57-63行目**: 関数のドキュメントコメント
2. **64-74行目**: `find_key` 関数の定義
3. **68-72行目**: foreach ループで各要素をチェック（キーも取得）
4. **69-71行目**: 述語が true を返したらキーを即座に返す
5. **73行目**: 見つからなかった場合は null を返す

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.php | `src/c/select.php` | 比較: C\find 関数との違い |

**主要処理フロー**:
- **24-34行目**: `C\find` 関数 - 値を返す（比較用）
- **31行目**: find は value を返す
- **70行目**: find_key は key を返す

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

```
C\find_key($traversable, $value_predicate)
    │
    └─ $value_predicate($value)  [ユーザー指定の述語関数]
```

### データフロー図

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

KeyedTraversable<Tk, Tv> ───┐
                            ├──▶ foreach + predicate適用 ──▶ ?Tk (キー or null)
predicate ──────────────────┘
                                    │
                                    v
                              値に対して述語を適用
                              キーを返す
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.php | `src/c/select.php` | ソース | C\find_key 関数の実装（64-74行目） |
| CSelectTest.php | `tests/c/CSelectTest.php` | テスト | find_key のユニットテスト（85-116行目） |
