---
title: "Como Filtrar Arrays e Slices em Zig"
url: "https://ziglang.com.br/receitas/como-filtrar-arrays-e-slices-em-zig/"
markdown_url: "https://ziglang.com.br/receitas/como-filtrar-arrays-e-slices-em-zig.MD"
description: "Aprenda a filtrar elementos de arrays e slices em Zig. Exemplos com funções genéricas, predicados e ArrayList para coleta de resultados."
date: "2026-02-21"
author: "Zig Brasil"
---

# Como Filtrar Arrays e Slices em Zig

Aprenda a filtrar elementos de arrays e slices em Zig. Exemplos com funções genéricas, predicados e ArrayList para coleta de resultados.


## Introdução

Filtrar arrays -- selecionar apenas os elementos que atendem a determinado critério -- é uma operação fundamental em qualquer linguagem. Em Zig, não existe uma função `filter` embutida como em linguagens funcionais, mas é simples implementar filtragem usando loops e `ArrayList`.

Nesta receita, você aprenderá a filtrar arrays de formas eficientes e reutilizáveis.

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja o [guia de instalação](/tutoriais/como-instalar-zig/)
- Conhecimento básico de Zig. Consulte a [introdução ao Zig](/tutoriais/introducao-ao-zig/)

## Filtragem Básica com Loop

A forma mais direta de filtrar:

```zig
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const numeros = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

    // Filtrar números pares
    var pares = std.ArrayList(i32).init(allocator);
    defer pares.deinit();

    for (numeros) |n| {
        if (@mod(n, 2) == 0) {
            try pares.append(n);
        }
    }

    std.debug.print("Pares: ", .{});
    for (pares.items) |n| std.debug.print("{d} ", .{n});
    std.debug.print("\n", .{});

    // Filtrar maiores que 7
    var grandes = std.ArrayList(i32).init(allocator);
    defer grandes.deinit();

    for (numeros) |n| {
        if (n > 7) {
            try grandes.append(n);
        }
    }

    std.debug.print("Maiores que 7: ", .{});
    for (grandes.items) |n| std.debug.print("{d} ", .{n});
    std.debug.print("\n", .{});
}
```

### Saída esperada

```
Pares: 2 4 6 8 10 12
Maiores que 7: 8 9 10 11 12
```

## Função de Filtro Genérica

Crie uma função reutilizável para filtrar qualquer tipo:

```zig
const std = @import("std");

fn filter(
    comptime T: type,
    allocator: std.mem.Allocator,
    items: []const T,
    comptime predicate: fn (T) bool,
) ![]T {
    var resultado = std.ArrayList(T).init(allocator);
    errdefer resultado.deinit();

    for (items) |item| {
        if (predicate(item)) {
            try resultado.append(item);
        }
    }

    return resultado.toOwnedSlice();
}

fn ehPositivo(n: i32) bool {
    return n > 0;
}

fn ehPar(n: i32) bool {
    return @mod(n, 2) == 0;
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const dados = [_]i32{ -5, 3, -1, 8, 0, -3, 12, 7, -2, 4 };

    const positivos = try filter(i32, allocator, &dados, ehPositivo);
    defer allocator.free(positivos);

    std.debug.print("Positivos: ", .{});
    for (positivos) |n| std.debug.print("{d} ", .{n});
    std.debug.print("\n", .{});

    const pares = try filter(i32, allocator, &dados, ehPar);
    defer allocator.free(pares);

    std.debug.print("Pares: ", .{});
    for (pares) |n| std.debug.print("{d} ", .{n});
    std.debug.print("\n", .{});
}
```

## Filtrar Strings

Filtrar uma lista de strings por critério:

```zig
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const palavras = [_][]const u8{
        "zig", "rust", "go", "c", "java", "python", "lua", "ruby", "zig-brasil",
    };

    // Filtrar palavras com mais de 3 caracteres
    var longas = std.ArrayList([]const u8).init(allocator);
    defer longas.deinit();

    for (&palavras) |palavra| {
        if (palavra.len > 3) {
            try longas.append(palavra);
        }
    }

    std.debug.print("Palavras com mais de 3 letras:\n", .{});
    for (longas.items) |p| std.debug.print("  - {s}\n", .{p});

    // Filtrar palavras que contêm "zig"
    var com_zig = std.ArrayList([]const u8).init(allocator);
    defer com_zig.deinit();

    for (&palavras) |palavra| {
        if (std.mem.indexOf(u8, palavra, "zig") != null) {
            try com_zig.append(palavra);
        }
    }

    std.debug.print("\nContêm \"zig\":\n", .{});
    for (com_zig.items) |p| std.debug.print("  - {s}\n", .{p});
}
```

## Filtrar Structs

Filtrar uma coleção de structs por campo:

```zig
const std = @import("std");

const Produto = struct {
    nome: []const u8,
    preco: f64,
    em_estoque: bool,
};

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const produtos = [_]Produto{
        .{ .nome = "Teclado", .preco = 199.90, .em_estoque = true },
        .{ .nome = "Monitor", .preco = 1899.00, .em_estoque = false },
        .{ .nome = "Mouse", .preco = 89.90, .em_estoque = true },
        .{ .nome = "Headset", .preco = 349.90, .em_estoque = true },
        .{ .nome = "Webcam", .preco = 459.00, .em_estoque = false },
        .{ .nome = "Mousepad", .preco = 49.90, .em_estoque = true },
    };

    // Filtrar disponíveis e abaixo de R$ 300
    var acessiveis = std.ArrayList(Produto).init(allocator);
    defer acessiveis.deinit();

    for (&produtos) |produto| {
        if (produto.em_estoque and produto.preco < 300.0) {
            try acessiveis.append(produto);
        }
    }

    std.debug.print("Produtos acessíveis em estoque (< R$300):\n", .{});
    for (acessiveis.items) |p| {
        std.debug.print("  {s}: R$ {d:.2}\n", .{ p.nome, p.preco });
    }
    std.debug.print("Total: {d} produtos\n", .{acessiveis.items.len});
}
```

### Saída esperada

```
Produtos acessíveis em estoque (< R$300):
  Teclado: R$ 199.90
  Mouse: R$ 89.90
  Mousepad: R$ 49.90
Total: 3 produtos
```

## Filtrar In-Place (Sem Alocação Extra)

Quando você pode modificar o array original e quer evitar alocação:

```zig
const std = @import("std");

fn filterInPlace(comptime T: type, slice: []T, comptime predicate: fn (T) bool) []T {
    var write_idx: usize = 0;
    for (slice) |item| {
        if (predicate(item)) {
            slice[write_idx] = item;
            write_idx += 1;
        }
    }
    return slice[0..write_idx];
}

fn maiorQue5(n: i32) bool {
    return n > 5;
}

pub fn main() !void {
    var dados = [_]i32{ 1, 8, 3, 12, 5, 7, 2, 9, 4, 11 };

    const resultado = filterInPlace(i32, &dados, maiorQue5);

    std.debug.print("Maiores que 5: ", .{});
    for (resultado) |n| std.debug.print("{d} ", .{n});
    std.debug.print("\n", .{});
    std.debug.print("Quantidade: {d}\n", .{resultado.len});
}
```

## Dicas e Boas Práticas

1. **Use `errdefer` ao construir resultados**: Garanta que `ArrayList` seja liberada em caso de erro durante a construção.

2. **`toOwnedSlice` transfere propriedade**: O chamador fica responsável por liberar a memória retornada.

3. **Filter in-place para performance**: Quando possível, modifique o slice original para evitar alocações.

4. **Combine com ordenação**: Filtre primeiro, depois ordene o resultado para melhor performance.

## Receitas Relacionadas

- [Arrays Dinâmicos com ArrayList](/receitas/zig-arraylist-dinamico/) - Base para filtragem
- [Ordenar Arrays e Slices](/receitas/zig-ordenar-array/) - Ordenar resultados filtrados
- [Busca Binária](/receitas/zig-busca-binaria/) - Buscar em dados filtrados
- [Como usar HashMap em Zig](/receitas/zig-hashmap-uso/) - Agrupar resultados

## Tutoriais Relacionados

- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
- [Gerenciamento de Memória em Zig](/tutoriais/gerenciamento-de-memoria-zig/)
