# Table (/docs/es_extended/shared/table)

`ESX.Table` collects small helpers for working with Lua tables: searching, filtering, mapping, copying and joining. They exist on client and server. In 1.16 they are implemented in [esx_lib](/docs/core/esx_lib) (`xLib.table`) and mapped onto `ESX.Table`.

## Overview [#overview]

| | |
|---|---|
| Resource | `es_extended` (implemented in `esx_lib`) |
| Side | Shared |
| Mapping | `es_extended/shared/compat.lua` |

"Array" below means a table with keys `1..n`. Functions marked *array* only look at that part and ignore other keys.

## Size and lookup [#size-and-lookup]

### ESX.Table.SizeOf [#esxtablesizeof]

```lua
ESX.Table.SizeOf(t)
```

**Returns:** `number` of keys, counted with `pairs`. Use it for tables with string keys.

```lua
print(ESX.Table.SizeOf({ police = 4, ambulance = 2 })) -- 2
```

### ESX.Table.Set [#esxtableset]

```lua
ESX.Table.Set(t)
```

*Array.* **Returns:** a set `{ [value] = true }` for fast membership checks.

```lua
local allowed = ESX.Table.Set({ 'police', 'sheriff', 'ambulance' })

if allowed[ESX.PlayerData.job.name] then
    OpenEmergencyMenu()
end
```

### ESX.Table.IndexOf [#esxtableindexof]

```lua
ESX.Table.IndexOf(t, value)
```

*Array.* **Returns:** first index of `value`, or `-1`.

### ESX.Table.LastIndexOf [#esxtablelastindexof]

```lua
ESX.Table.LastIndexOf(t, value)
```

*Array.* **Returns:** last index of `value`, or `-1`.

### ESX.Table.Find [#esxtablefind]

```lua
ESX.Table.Find(t, cb)
```

*Array.* **Returns:** the first element for which `cb(element)` is truthy, or `nil`.

```lua
local bread = ESX.Table.Find(ESX.PlayerData.inventory, function(item)
    return item.name == 'bread'
end)
```

### ESX.Table.FindIndex [#esxtablefindindex]

```lua
ESX.Table.FindIndex(t, cb)
```

*Array.* **Returns:** index of the first match, or `-1`.

### ESX.Table.TableContains [#esxtabletablecontains]

```lua
ESX.Table.TableContains(tab, val)
```

| Name | Type | Description |
|---|---|---|
| `tab` | `table` | Table to search (all values, not only the array part). |
| `val` | `any \| table` | Value, or a table of values. With a table, returns `true` if **any** of them is in `tab`. |

**Returns:** `boolean`

```lua
local emergencyJobs = { 'police', 'ambulance' }
print(ESX.Table.TableContains(emergencyJobs, ESX.PlayerData.job.name))
```

## Transform [#transform]

### ESX.Table.Filter [#esxtablefilter]

```lua
ESX.Table.Filter(tbl, filter)
```

| Name | Type | Description |
|---|---|---|
| `tbl` | `table` | Table to filter. |
| `filter` | `function` | `function(value, key)`. Return `true` to keep the entry. |

**Returns:** a new table with the kept entries **under their original keys**.

```lua
local stacks = ESX.Table.Filter(ESX.PlayerData.inventory, function(item)
    return item.count > 0
end)

local list = ESX.Table.ToArray(stacks) -- re-index to 1..n
```

### ESX.Table.Map [#esxtablemap]

```lua
ESX.Table.Map(t, cb)
```

*Array.* **Returns:** a new array with `cb(element, index)` for each element.

```lua
local names = ESX.Table.Map(ESX.PlayerData.inventory, function(item)
    return item.label
end)
```

### ESX.Table.Reverse [#esxtablereverse]

```lua
ESX.Table.Reverse(t)
```

*Array.* **Returns:** a new array in reverse order.

### ESX.Table.Clone [#esxtableclone]

```lua
ESX.Table.Clone(t)
```

**Returns:** a deep copy, including nested tables and the metatable. Non-table values are returned as they are.

```lua
local defaults = { hunger = 100, thirst = 100 }
local status = ESX.Table.Clone(defaults)
status.hunger = 50 -- defaults.hunger stays 100
```

### ESX.Table.Concat [#esxtableconcat]

```lua
ESX.Table.Concat(t1, t2)
```

**Returns:** a deep copy of `t1` with the array elements of `t2` appended. Neither input is changed.

### ESX.Table.Join [#esxtablejoin]

```lua
ESX.Table.Join(t, sep)
```

*Array.* Joins elements into a string.

| Name | Type | Description |
|---|---|---|
| `t` | `table` | Array of strings or numbers. |
| `sep` | `string?` | Separator. Default `,`. |

**Returns:** `string`

```lua
print(ESX.Table.Join({ 'bread', 'water', 'phone' }, ', ')) -- bread, water, phone
```

### ESX.Table.ToArray [#esxtabletoarray]

```lua
ESX.Table.ToArray(t)
```

**Returns:** a new array with all values of `t` (order follows `pairs` and is not guaranteed).

### ESX.Table.Sort [#esxtablesort]

```lua
ESX.Table.Sort(t, order)
```

Returns an **iterator** over `t` sorted by key. It does not sort `t` in place.

| Name | Type | Description |
|---|---|---|
| `t` | `table` | Table to iterate. |
| `order` | `function?` | `function(t, keyA, keyB)` returning `true` if `keyA` comes first. Default: sort keys ascending. |

**Returns:** iterator `function` yielding `key, value`.

```lua
local salaries = { police = 300, ambulance = 250, mechanic = 200 }

for job, salary in ESX.Table.Sort(salaries, function(t, a, b) return t[a] > t[b] end) do
    print(job, salary)
end
```

### ESX.Table.Wipe [#esxtablewipe]

```lua
ESX.Table.Wipe(t)
```

Removes every key from `t` in place, keeping the same table reference.

<Callout type="warn">
The `ESX.Table` functions run inside `es_extended`. When you call them from another resource, your table is copied on the way in. Functions that return a new value work as expected, but `ESX.Table.Wipe` only clears that copy. Use `table.wipe(t)` or `xLib.table.wipe(t)` in your own resource instead.
</Callout>

## Debugging [#debugging]

`ESX.DumpTable(t)` prints tables in readable form. It is documented on [Shared functions](/docs/es_extended/shared).

## Related [#related]

- [Shared functions](/docs/es_extended/shared)
- [Math functions](/docs/es_extended/shared/math)
- [Timeout functions](/docs/es_extended/shared/timeout)
- [esx_lib](/docs/core/esx_lib)
