---
source: https://carbone.io/documentation/design/repetitions/filtering.html
title: "Filter your JSON array while printing values in your report"
description: "Filter your array"
generated_at: "2026-07-13"
---

# Filtering arrays

Filter your array  
COMMUNITY FEATURE Available for:  
✓ Carbone Cloud  
✓ Carbone On-premise  
✓ Embedded Carbone JS   v2.0+ 

> ℹ️ **Note:** Tips: To hide a row in a table with a complex condition, using a [Smart Conditional Block](/documentation/design/conditions/smart-conditions.md#drop-keep-element) is often easier to manage. See the simple [example below](#smart-filter).

## New syntax in v5+

NEW v5.0.0+

Prior to Carbone v5, filters needed to be repeated on all `[i]` tags, like in most examples on this page.

With **v5 and later, a single `[i+1]` tag containing the filter is sufficient**. Repeating the filter is unnecessary. It works for all types of array filters described on this page.

Carbone v5 still supports the v4 syntax for backward compatibility, where the filter must be repeated on all tags.

```cdata
[
  { "name": "John", "age": 20 },
  { "name": "Eva", "age": 18 },
  { "name": "Bob", "age": 25 },
  { "name": "Charly", "age": 30 }
]
```

**Template:**

| People |
| --- |
| {d[i].name} {d[i].age} |
| {d[i+1, age > 19, age < 30].name} |

**Result:**

| People |
| --- |
| John 20 |
| Bob 25 |

## Number filters

You can use conditional operators to filter arrays: `>` , `<` , `>=` , `<=` , `=`, `!=`.

Since Carbone v5, filters must be the same on all tags if you want to keep only matching rows. Otherwise, only the tag is hidden, not the entire row.

Use [Aliases](/documentation/design/substitutions/aliases.md) to simplify report maintenance and avoid repetitions of code.

```cdata
[
  { "name": "John", "age": 20 },
  { "name": "Eva", "age": 18 },
  { "name": "Bob", "age": 25 },
  { "name": "Charly", "age": 30 }
]
```

**Template:**

| People |
| --- |
| {d[i, age > 19, age < 30].name} |
| {d[i+1, age > 19, age < 30 ].name} |

**Result:**

| People |
| --- |
| John |
| Bob |

You can add multiple filters by separating them with commas. Each comma represents an `AND` operator, so all conditions must be met for the filter to apply. If you need to use an `OR` operator, see the [advanced filter example](#advanced-filter).

## String filters

String values can also be used for filtering, as shown in the following example. Both `=` and `!=` operators are supported.

```cdata
[
  { "name": "Falcon 9", "type": "rocket" },
  { "name": "Model S", "type": "car" },
  { "name": "Model 3", "type": "car" },
  { "name": "Falcon Heavy", "type": "rocket" }
]
```

**Template:**

| People |
| --- |
| {d[i , type='rocket'].name} |
| {d[i+1, type='rocket'].name} |

**Result:**

| People |
| --- |
| Falcon 9 |
| Falcon Heavy |

## Filter the first N items

Filtering the loop index is also possible, as shown in the following example:

```cdata
[
  { "name": "Falcon 9" },
  { "name": "Model S" },
  { "name": "Model 3" },
  { "name": "Falcon Heavy" }
]
```

**Template:**

| People |
| --- |
| {d[i, i < 2].name} |
| {d[i+1, i < 2].name} |

**Result:**

| People |
| --- |
| Falcon 9 |
| Model S |

Get inspired by one of our real-life examples: [Best Manufacturer Awards](/examples/classification-simple/index.md)

## Exclude the last N items

Negative loop index `i` is accepted to print all elements except the last N items:

```cdata
[
  { "name": "Falcon 9" },
  { "name": "Model S" },
  { "name": "Model 3" },
  { "name": "Falcon Heavy" }
]
```

```ctemplate
### The last item
{d[i=-1].name} 
### Exclude the last item
| People |
| --- |
| {d[i, i!=-1].name} |
| {d[i+1, i!=-1].name} |
### Exclude the last two items
| People |
| --- |
| {d[i, i<-2].name} |
| {d[i+1, i<-2].name} |
```

```cresult
### The last item
Falcon Heavy 
### Exclude the last item
| People |
| --- |
| Falcon 9 |
| Model S |
| Model 3 |
### Exclude the last two items
| People |
| --- |
| Falcon 9 |
| Model S |
```

## Advanced filter

NEW v5.0.0+

When your filter is complex (for example, if you need "OR" logic, or mathematical calculations), you can first store an intermediate result using the `set` formatter.

In the example below, we want to keep only the rows where the name contains either "3" or "9". The [set formatter](/documentation/design/computation/store-and-transform.md#modify-json-set-relativepath) is used to create a new attribute called `.isShown` in the JSON, which indicates whether each item matches the complex condition:

`{d[].name:ifIN(3):or:ifIN(9):show(1):elseShow(0):set(.isShown)}`

Then, you can use this new attribute as a filter for the array.

```cdata
[
  { "name": "Falcon 9" },
  { "name": "Model S" },
  { "name": "Model 3" },
  { "name": "Falcon Heavy" }
]
```

```ctemplate
{d[].name:ifIN(3):or:ifIN(9):show(1):elseShow(0):set(.isShown)}
| People |
| --- |
| {d[i].name} |
| {d[i+1, isShown=1].name} |
```

```cresult
| People |
| --- |
| Falcon 9 |
| Model 3 |
```

## Smart filter

Sometimes, it is easier to use a [Smart Conditional Block](/documentation/design/conditions/smart-conditions.md#drop-keep-element) to hide a row in a table:

You can use complex conditions with formatters.

```cdata
[
  { "name": "Falcon 9" },
  { "name": "Model S" },
  { "name": "Model 3" },
  { "name": "Falcon Heavy" }
]
```

**Template:**

| People |
| --- |
| {d[i].name}{d[i].name:ifIN('Falcon'):drop(row)} |
| {d[i+1].name} |

**Result:**

| People |
| --- |
| Model S |
| Model 3 |

## Related topics

- [Loop over object properties](/documentation/design/repetitions/with-objects.md)
- [Loop over array](/documentation/design/repetitions/with-arrays.md)
- [Sorting arrays](/documentation/design/repetitions/sorting.md)
- [Lookup](/documentation/design/repetitions/lookup.md)
- [Grouping](/documentation/design/repetitions/grouping.md)
- [Distinct](/documentation/design/repetitions/distinct.md)
