Cómo eliminar un elemento de un slice en Golang: guía completa con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Cómo eliminar un elemento de un Slice en Golang: guía detallada con ejemplos

\n\n

Trabajar con slices en Go es la rutina diaria de todo desarrollador. Pero una operación genera dudas incluso entre los "gophers" experimentados: eliminar un elemento de un slice. Parecería que no tiene nada de complicado. Sin embargo, Go no tiene un método incorporado delete() para slices, como sí lo tiene para los mapas. Hay que ingeniárselas.

\n\n

En este artículo analizaremos todas las formas de eliminar un elemento de un slice en Golang: desde la simple eliminación por índice hasta trucos avanzados para mantener el orden y optimizar la memoria. Aprenderás cómo funciona la mecánica interna de los slices, por qué la simple asignación no siempre funciona y cómo evitar errores típicos.

\n\n

¿Por qué Go no tiene una función incorporada para eliminar de un slice?

\n\n

Antes de sumergirnos en el código, analicemos la filosofía del lenguaje. Un slice en Go es simplemente una "ventana" hacia un array subyacente. No posee los datos, solo hace referencia a ellos. Por lo tanto, eliminar un elemento no es un borrado físico de datos de la memoria (como en C++), sino una reestructuración de la "ventana" mediante hábiles operaciones de append y slicing.

\n\n

Go te deja decidir cómo organizar la eliminación: manteniendo el orden o no, reduciendo la capacidad o no. Esto brinda flexibilidad, pero requiere comprensión.

\n\n

Método 1: Eliminación por índice (manteniendo el orden)

\n\n

Este es el caso más común. Tienes un slice y quieres eliminar el elemento en la posición i, conservando el orden relativo de los elementos restantes.

\n\n
package main\n\nimport "fmt"\n\nfunc removeIndex(s []int, index int) []int {\n    // Une la parte anterior al índice y la parte posterior al índice\n    return append(s[:index], s[index+1:]...)\n}\n\nfunc main() {\n    slice := []int{1, 2, 3, 4, 5}\n    slice = removeIndex(slice, 2) // elimina el elemento en el índice 2 (valor 3)\n    fmt.Println(slice) // [1 2 4 5]\n}\n
\n\n

¿Cómo funciona?

\n
    \n
  • s[:index] — toma todos los elementos hasta el que se va a eliminar (sin incluirlo).
  • \n
  • s[index+1:] — toma todos los elementos después del que se va a eliminar.
  • \n
  • append combina estas dos "partes" en un solo slice.
  • \n
\n\n

Importante: Este método modifica el array subyacente. Después de la operación, el elemento 3 permanecerá físicamente en la memoria (se sobrescribirá solo si agregas nuevos elementos). Pero para ti, "desapareció" del slice.

\n\n

Método 2: Eliminación por índice (sin mantener el orden) — método rápido

\n\n

Si el orden de los elementos no es importante (por ejemplo, trabajas con un conjunto de datos desordenado), puedes usar el truco de "reemplazar con el último":

\n\n
func removeFast(s []int, index int) []int {\n    // Reemplaza el elemento a eliminar con el último\n    s[index] = s[len(s)-1]\n    // Recorta el slice, descartando el último elemento\n    return s[:len(s)-1]\n}\n\nfunc main() {\n    slice := []int{1, 2, 3, 4, 5}\n    slice = removeFast(slice, 1) // elimina el elemento en el índice 1 (valor 2)\n    fmt.Println(slice) // [1 5 3 4] — ¡el orden se ha alterado!\n}\n
\n\n

¿Por qué es más rápido? Porque no copiamos la mitad del slice. Simplemente movemos un elemento (el último) al lugar del que se elimina y truncamos el slice. Operación O(1) frente a O(n) del primer método.

\n\n

Cuándo usarlo: En bucles críticos, cuando el rendimiento es primordial y el orden no importa (por ejemplo, al eliminar de un pool de objetos).

\n\n

Método 3: Eliminación por valor (primera aparición)

\n\n

A menudo es necesario encontrar y eliminar un elemento por su valor, no por su índice. Para ello, primero encontramos el índice y luego aplicamos uno de los métodos anteriores.

\n\n
func removeByValue(s []string, value string) []string {\n    for i, v := range s {\n        if v == value {\n            return append(s[:i], s[i+1:]...)\n        }\n    }\n    return s // si no se encuentra, devuelve el slice original\n}\n

Blogs

Book Recommendations