---
name: join_by_key
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func JoinByKey(left, right []map[string]any, key, how string) []map[string]any"
description: "Join de dos slices de map[string]any por una clave comun. Soporta inner, left, right y outer. Campos duplicados del right se sufijan con _right. Algoritmo O(n+m)."
tags: [tabular, join, merge, go, core, pendiente-usar]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
params:
  - name: left
    desc: "slice izquierdo de map[string]any a unir"
  - name: right
    desc: "slice derecho de map[string]any a unir"
  - name: key
    desc: "nombre del campo común a usar como clave de unión"
  - name: how
    desc: "tipo de unión: 'inner', 'left', 'right', 'outer'"
output: "slice de map[string]any con el resultado de la unión; campos duplicados del right se sufijan con '_right'"
tested: true
tests:
  - "Inner join solo matches"
  - "Left join todos los left con nil para right sin match"
  - "Right join"
  - "Outer join"
  - "Campos duplicados con sufijo _right"
  - "Key ausente en alguna fila"
test_file_path: "functions/core/join_by_key_test.go"
file_path: "functions/core/join_by_key.go"
---

## Ejemplo

```go
left := []map[string]any{{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}}
right := []map[string]any{{"id": 1, "dept": "eng"}, {"id": 3, "dept": "sales"}}

result := JoinByKey(left, right, "id", "inner")
// [{"id": 1, "name": "Alice", "dept": "eng"}]

result = JoinByKey(left, right, "id", "left")
// [{"id": 1, "name": "Alice", "dept": "eng"},
//  {"id": 2, "name": "Bob", "dept": nil}]
```

## Notas

Funcion pura sin dependencias externas.
El algoritmo indexa right en O(n) y luego itera left en O(m), total O(n+m).
Los campos de right que colisionan con campos de left (excepto la clave) se renombran con sufijo _right.
Un key puede tener multiples filas en right — se generan multiples filas en el resultado (comportamiento de join relacional).
