# List filters

> Filters for arrays, hashes and other collections.

These filters work with arrays, hashes and other collections. Filters never change the original value. They return a new one.

The examples use this data:

```ts
posts = [
	{ title: "Hello", author: "Ada", date: "2026-03-01", views: 120 },
	{ title: "Layouts", author: "Grace", date: "2026-01-15", views: 340 },
	{ title: "Workers", author: "Ada", date: "2026-02-10", views: 90 },
]
```

## `length`

Counts the items in an array, the keys in a hash, or the characters in a string. A hash or map counts the entries a loop would see. Null has a length of 0.

page.kiln:

```kiln
{{ posts|length }} posts, {{ "héllo"|length }} letters
```

Output:

```html
3 posts, 5 letters
```

## `first` and `last`

Return the first or last item, or null when there are none. On a string they return a character.

page.kiln:

```kiln
{{ (posts|first).title }} and {{ (posts|last).title }}
```

Output:

```html
Hello and Workers
```

## `slice`

Returns part of an array or string, from a start index up to, but not including, an end index. Negative numbers count from the end, as in JavaScript.

page.kiln:

```kiln
{{ [1, 2, 3, 4, 5]|slice(1, 3)|join(", ") }}
{{ [1, 2, 3, 4, 5]|slice(-2)|join(", ") }}
```

Output:

```html
2, 3
4, 5
```

## `join`

Joins items into a string. A second separator goes between the last two items.

page.kiln:

```kiln
{{ ["tea", "coffee", "water"]|join(", ", " and ") }}
```

Output:

```html
tea, coffee and water
```

## `keys`

Returns the keys of a hash or map, or the indexes of an array.

page.kiln:

```kiln
{{ { a: 1, b: 2 }|keys|join(", ") }}
```

Output:

```html
a, b
```

## `merge`

Joins arrays together, or combines hashes. For hashes, later keys win. Mixing arrays and hashes is an error.

page.kiln:

```kiln
{{ [1, 2]|merge([3], [4])|join(", ") }}
{{ ({ size: "md", tone: "plain" }|merge({ size: "lg" })).size }}
```

Output:

```html
1, 2, 3, 4
lg
```

## `reverse`

Reverses an array, string or hash. A hash keeps its keys.

page.kiln:

```kiln
{{ [1, 2, 3]|reverse|join(", ") }} {{ "kiln"|reverse }}
```

Output:

```html
3, 2, 1 nlik
```

## `sort`

Returns a sorted copy. Without an argument, it sorts numbers, strings or dates in natural order. With a one-parameter arrow function, it sorts by the result. With a two-parameter one, it uses it to compare items, like JavaScript's `sort`. A hash keeps its keys, sorted by their values.

page.kiln:

```kiln
{{ [3, 1, 2]|sort|join(", ") }}
{{ posts|sort(p => p.date)|column("title")|join(", ") }}
{{ posts|sort((a, b) => b.views - a.views)|column("title")|join(", ") }}
```

Output:

```html
1, 2, 3
Layouts, Workers, Hello
Layouts, Hello, Workers
```

## `map`

Calls an arrow function for each item and returns the results. The function gets the value and the key.

page.kiln:

```kiln
{{ posts|map(p => p.title|upper)|join(", ") }}
```

Output:

```html
HELLO, LAYOUTS, WORKERS
```

## `filter`

Keeps the items for which the arrow function returns true.

page.kiln:

```kiln
{{ posts|filter(p => p.author == "Ada")|column("title")|join(", ") }}
```

Output:

```html
Hello, Workers
```

## `reduce`

Combines the items into one value. The arrow function gets the running total, the value and the key. The second argument is the starting value. Without it, the total starts as null, which can't be added to, so pass 0 to add up numbers.

page.kiln:

```kiln
{{ posts|reduce((total, p) => total + p.views, 0) }} views
```

Output:

```html
550 views
```

## `find`

Returns the first item for which the arrow function returns true, or null.

page.kiln:

```kiln
{{ (posts|find(p => p.views > 200)).title }}
```

Output:

```html
Layouts
```

## `column`

Reads one property from each item.

page.kiln:

```kiln
{{ posts|column("author")|join(", ") }}
```

Output:

```html
Ada, Grace, Ada
```

## `batch`

Splits an array into groups of a given size. Pass a second argument to fill up the last group.

page.kiln:

```kiln
{% for row in [1, 2, 3, 4, 5]|batch(2, "-") %}
	<div>{{ row|join(" ") }}</div>
{% endfor %}
```

Output:

```html
<div>1 2</div>
<div>3 4</div>
<div>5 -</div>
```

## `default`

Returns a fallback when the value is [empty](https://kilnlang.com/docs/language/values/#empty-values) or missing. In strict mode, it also stops a missing value from being an error.

page.kiln:

```kiln
{{ page.subtitle|default("No subtitle") }}
```

Output:

```html
No subtitle
```
