# 機能設計書 73-map_with_key

## 概要

本ドキュメントは、Hack Standard Library（HSL）のVec名前空間が提供する`map_with_key`関数の機能設計を記述する。この関数は、KeyedTraversableの各要素に対して、キーと値の両方を引数として変換関数を適用し、結果を新しいvecとして返却する機能を提供する。

### 本機能の処理概要

`Vec\map_with_key`関数は、`Vec\map`の拡張版として、変換処理においてキー情報も活用できるようにした関数である。KeyedTraversableの各要素について、キーと値のペアを変換関数に渡し、変換結果を新しいvecとして返却する。

**業務上の目的・背景**：データ変換において、値だけでなくキー（インデックスや連想配列のキー）も変換ロジックに必要な場合がある。例えば、インデックス番号を含む文字列を生成する、キーと値を組み合わせたオブジェクトを作成するなどのケースである。`map_with_key`関数は、このような変換処理を簡潔に記述することを可能にする。

**機能の利用シーン**：
- 配列のインデックスを含む文字列を生成する（例: "0: apple", "1: banana"）
- キーと値を組み合わせて新しいデータ構造を作成する
- インデックスベースの計算を行う（例: index * value）
- 連想配列のキーを値に含める変換を行う

**主要な処理内容**：
1. 入力としてKeyedTraversableと変換関数を受け取る
2. KeyedTraversableの各要素をキーと値のペアでイテレートする
3. 各要素に対してキーと値を引数として変換関数を適用する
4. 変換結果を結果vecに追加する
5. すべての変換結果を含む新しいvecを返却する

**関連システム・外部連携**：本機能は純粋な関数であり、外部システムとの連携はない。

**権限による制御**：本機能は純粋関数であり、権限による制御は適用されない。関数シグネチャの`[ctx $value_func]`は、変換関数のコンテキストを伝播することを示す。

## 関連画面

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

## 機能種別

計算処理 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| $traversable | KeyedTraversable<Tk, Tv1> | Yes | 変換対象のキー付きコレクション | なし（空コレクションも許容） |
| $value_func | (function(Tk, Tv1)[_]: Tv2) | Yes | キーと値を受け取り変換結果を返す関数 | なし |

### 入力データソース

関数引数として直接渡される。KeyedTraversableとして許容される型には、vec、dict、keyset、Vector、Map、およびカスタムKeyedIteratorが含まれる。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | vec<Tv2> | 変換関数を適用した結果を含む新しいvec |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 空のvecを結果として初期化
   └─ $result = vec[]
2. KeyedTraversableをキーと値でイテレート
   └─ foreach ($traversable as $key => $value)
3. 変換関数にキーと値を渡して実行
   └─ $value_func($key, $value)
4. 変換結果を結果vecに追加
   └─ $result[] = $value_func($key, $value)
5. 完成した結果vecを返却
   └─ return $result
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[result = vec空配列を初期化]
    B --> C{traversableに次の要素があるか}
    C -->|Yes| D[次のkeyとvalueを取得]
    D --> E[value_funcにkeyとvalueを渡して実行]
    E --> F[変換結果をresultに追加]
    F --> C
    C -->|No| G[resultを返却]
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | 順序保持 | 入力順序が出力で保持される | 常時 |
| BR-73-02 | 要素数保持 | 入力と出力の要素数は同一 | 常時 |
| BR-73-03 | 空入力処理 | 空のKeyedTraversableは空のvecを返す | 入力が空の場合 |
| BR-73-04 | キー参照 | 変換関数はキーを第1引数として受け取る | 常時 |
| BR-73-05 | コンテキスト伝播 | 変換関数のコンテキストが伝播される | 常時 |

### 計算ロジック

変換関数$value_funcに依存する。典型的な使用例として、`($k, $v) ==> (string)$k . $v`のようなキーと値の結合がある。

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

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 変換関数内例外 | $value_funcが例外をスローした場合 | 呼び出し元で適切にハンドリング |

### リトライ仕様

本機能にリトライ仕様はない。

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

本機能はデータベーストランザクションを使用しない。

## パフォーマンス要件

- 時間計算量: O(n * f) - nは入力要素数、fは変換関数の計算量
- 空間計算量: O(n) - 結果格納用のvec

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

本機能は純粋関数であり、特別なセキュリティ考慮事項はない。変換関数内でのセキュリティ処理は呼び出し元の責務となる。

## 備考

- キーを使用しない変換の場合は`Vec\map`を使用する
- コンテキスト記法`[ctx $value_func]`により、変換関数の副作用特性が伝播される

---

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

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

### 推奨読解順序

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

`map_with_key`関数で扱うデータ型は、キー付きジェネリクスを用いた型変換パターンである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Hack言語組み込み型 | - | KeyedTraversable<Tk, Tv1>の構造を理解する。Tkはキー型、Tv1は値型 |

**読解のコツ**: HackにおけるKeyedTraversableは、キーと値のペアを反復可能な型である。foreach ($x as $key => $value)の形式でイテレートできる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | transform.php | `src/vec/transform.php` | map_with_key関数の定義と実装を確認 |

**主要処理フロー**:
1. **116-119行目**: 関数シグネチャ - 3つのジェネリック型Tk, Tv1, Tv2とコンテキスト伝播
2. **120行目**: 空のvecで結果を初期化
3. **121-123行目**: foreachでキーと値のペアをイテレート
4. **124行目**: 結果を返却

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | VecTransformTest.php | `tests/vec/VecTransformTest.php` | map_with_key関数のテストケースを確認 |

**主要処理フロー**:
- **202-220行目**: provideTestMapWithKeyメソッドでテストデータを提供
- **203-208行目**: 空配列のテストケース
- **209-213行目**: Vectorでインデックスと値を結合するケース
- **214-218行目**: Vec\rangeでインデックスと値を乗算するケース
- **222-229行目**: 実際のテスト実行メソッド

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

```
呼び出し元コード
    │
    └─ Vec\map_with_key($traversable, $value_func)
           │
           └─ foreach ループ（キーと値）
                  │
                  └─ $value_func($key, $value) を各要素に適用
                         │
                         └─ 結果をvecに追加
```

### データフロー図

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

KeyedTraversable<Tk, Tv1>  ───┐
                              │
                              ├──▶  foreachループで      ───▶  vec<Tv2>
                              │     各要素に$value_funcを
$value_func(Tk, Tv1)     ─────┘     適用（キーと値を渡す）

例:
Vector{'the', 'quick'}    ───▶  ($k, $v) ==> (string)$k.$v  ───▶  vec['0the', '1quick']
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| transform.php | `src/vec/transform.php` | ソース | map_with_key関数の実装 |
| VecTransformTest.php | `tests/vec/VecTransformTest.php` | テスト | map_with_key関数のユニットテスト |
