# Metodos y chaining en string/list/dict

## Objetivo de aprendizaje
- Aplicar metodos y encadenamiento para codigo mas legible.

## Sintaxis clave
```lucia
let text: string = "  Lucia Lang  ";
let parts: list<string> = text.trim().lower().split(" ");
```

## Ejemplos
- String: `upper`, `lower`, `trim`, `ltrim`, `rtrim`, `split`, `join`, `contains`, `starts_with`, `ends_with`, `replace`, `indexOf`, `repeat`, `substring`, `pad_left`, `pad_right`, `to_int`, `to_float`, `to_bool`, `count`, `capitalize`, `title`, `is_numeric`, `is_alpha`, `is_alnum`.
- List: `append`, `pop`, `contains`, `sort`, `reverse`, `indexOf`, `slice`, `clear`, `insert`, `remove`, `removeAt`, `extend`, `first`, `last`, `is_empty`, `copy`.
- Dict: `keys`, `values`, `contains_key`, `get`, `clear`, `remove`, `items`, `is_empty`, `size`, `merge`, `put`.

## Ejemplos de chaining
```lucia
let cleaned: string = "  Lucia  ".trim().lower();
let words: list<string> = cleaned.split(" ");
let csv: string = ",".join(words);
```

```lucia
let nums: list<int> = [3, 1, 2];
nums.sort();
let top2: list<int> = nums.slice(0, 2);
print(top2.contains(2));
```

```lucia
let stats: dict<string, int> = {"wins": 3};
let wins: int = stats.get("wins", 0);
print(stats.keys());
print(stats.values());
let merged: dict<string, int> = stats.merge({"losses": 1});
stats.put("draws", 2);
print(stats.items());
```

```lucia
let nums: list<int> = [3, 1, 2];
nums.insert(1, 99);
nums.remove(2);
let removed: int = nums.removeAt(0);
nums.extend([7, 8]);
print(nums.first());
print(nums.last());
print(nums.is_empty());
let copyNums: list<int> = nums.copy();
nums.clear();
print(removed);
print(copyNums);
```

```lucia
let s: string = "  lucia editor  ";
print(s.ltrim());
print(s.rtrim());
print("7".pad_left(3, "0"));
print("A".pad_right(3, "_"));
print("42".to_int());
print("3.14".to_float());
print("yes".to_bool());
print("banana".count("a"));
print("lucia".capitalize());
print("lucia editor".title());
print("123".is_numeric());
print("abc".is_alpha());
print("abc123".is_alnum());
```

## Contratos importantes
- `append` recibe un elemento compatible con `list<T>`.
- `pop` no recibe argumentos.
- `get` acepta 1 o 2 argumentos: llave y default opcional.
- `insert` requiere `(index: int, value: T)`.
- `removeAt` requiere `(index: int)`.
- `extend` requiere `list<T>` compatible con el receptor.
- `put` requiere `(key: K, value: V)` compatible con el tipo del diccionario.
- `pad_left` / `pad_right` requieren `width: int` y `fill: string` opcional.
- `slice` y `substring` usan indices int.
- El tamano se obtiene con `len(x)`, no con `.length()`.

## Nota entre targets
- `dict.get(key)` difiere cuando la llave no existe:
	- Target Python: retorna `None`
	- Target JavaScript: retorna `undefined`
- `dict.get(key, default)` se comporta de forma consistente en ambos targets.

## Errores comunes
- Llamar metodos que no pertenecen al tipo receptor.
- Ignorar contrato de argumentos.

## Tip de migracion
- Si vienes de JavaScript, reemplaza `arr.length` o `arr.length()` por `len(arr)`.

## Practica sugerida
- Normaliza una lista de nombres y genera una linea CSV.

## Relacionados
- types-and-collections
- string-interpolation
