¿Cómo usar std.mem.indexOfScalar?

¿Cómo usar std.mem.indexOfScalar?

Cuando trabajamos con colecciones en Zig, a menudo necesitamos localizar la posición de un elemento específico dentro de un slice. La función std.mem.indexOfScalar está diseñada justamente para ese propósito, permitiendo buscar un valor escalar en un slice de cualquier tipo. En este artículo veremos cómo usarla, entender su firma, y explorar algunos ejemplos útiles con comentarios explicativos.

Fundamentos de std.mem.indexOfScalar

La declaración de la función se encuentra en el módulo std.mem y tiene la siguiente firma:

pub fn indexOfScalar(comptime T: type, haystack: []const T, needle: T) ?usize
  • T: El tipo de los elementos del slice. Se pasa como parámetro de tipo en tiempo de compilación (comptime).
  • haystack: Slice de tipo []const T donde se buscará.
  • needle: Valor escalar del tipo T que se desea encontrar.
  • Retorno: ?usize – si el elemento se encuentra, devuelve su índice; si no, devuelve null.

Esta función es muy similar a std.mem.indexOf, pero en lugar de comparar slices, compara un solo valor escalar contra cada elemento del slice.

Casos de uso típicos

  • Buscar un carácter dentro de un string.
  • Localizar un número dentro de un array de enteros.
  • Encontrar la posición de una estructura con un campo específico.
  • Filtrar índices donde un valor aparece en un vector de booleanos.

Ejemplo 1: Buscar un carácter en un string

Supongamos que tenemos un string literal y queremos saber dónde aparece la letra ‘a’.

const std = @import("std");

pub fn main() void {
    // String literal (slice de u8)
    const haystack: []const u8 = "zig is fun, a language!";

    // Valor que queremos encontrar: 'a'
    const needle: u8 = 'a';

    // Llamamos a indexOfScalar
    const idx = std.mem.indexOfScalar(u8, haystack, needle);

    // Comprobamos si se encontró
    if (idx) |i| {
        // Si se encontró, imprimimos el índice
        std.debug.print("La letra 'a' se encuentra en la posición {d}\\n", .{i});
    } else {
        // Si no se encontró, informamos al usuario
        std.debug.print("La letra 'a' no se encontró en el texto.\\n", .{});
    }
}

Comentarios línea por línea:

  • const std = @import("std"); – Importamos el módulo estándar.
  • const haystack: []const u8 = "zig is fun, a language!"; – Creamos un slice de u8 (bytes) a partir de un literal.
  • const needle: u8 = 'a'; – Declaramos el carácter que buscamos.
  • const idx = std.mem.indexOfScalar(u8, haystack, needle); – Ejecutamos la función. El primer argumento es el tipo u8; Zig infiere el resto.
  • if (idx) |i| { ... } – Usamos un if con desempaquetado opcional para manejar el caso null.
  • std.debug.print(...); – Imprimimos el resultado.

Ejemplo 2: Buscar un número entero en un array

Ahora busquemos la posición del número 42 dentro de un array de enteros.

const std = @import("std");

pub fn main() void {
    // Array de enteros (slice de i32)
    const numbers: []const i32 = &.{10, 20, 42, 50, 60};

    // Valor que queremos buscar
    const target: i32 = 42;

    // Uso de indexOfScalar
    const pos = std.mem.indexOfScalar(i32, numbers, target);

    if (pos) |p| {
        std.debug.print("El número {d} aparece en el índice {d}.\\n", .{target, p});
    } else {
        std.debug.print("El número {d} no se encontró.\\n", .{target});
    }
}

Detalles:

  • &.{10, 20, 42, 50, 60} crea un slice inmutable con los valores indicados.
  • El retorno es opcional; se maneja con if (pos) |p| { ... }.

Ejemplo 3: Buscar una estructura por un campo específico

Imaginemos una lista de estructuras que representan personas y queremos encontrar la primera con un nombre determinado.

const std = @import("std");

const Person = struct {
id: u32,
name: []const u8,
};

pub fn main() void {
// Lista de personas
const people: []const Person = &.{
.{ .id = 1, .name = "Alice" },
.{ .id = 2, .name = "Bob" },
.{ .id = 3, .name = "Carol" },
};

// Valor que buscamos (nombre)
const targetName: []const u8 =

Comments

No comments yet. Why don’t you start the discussion?

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *