Как удалить элемент из массива golang
Перейти к содержимому

Как удалить элемент из массива golang

  • автор:

Удалить все элементы массива b из массива a

Могли бы подсказать, что у меня не так в коде, а то уже запутался?
Условие задачи в топике, на простых тестах все работает как надо.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
package main import "fmt" func main()  var a = []int1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 1, 2, 2, 3, 4, 5> var b = []int1, 2, 3, 4, 5> c := ArrayDiff(a, b) fmt.Printf("%v - cap: %d; len - %d\n", c, cap(c), len(c)) > func ArrayDiff(a, b []int) []int  if len(b) == 0  return a > else if len(a) == 0  return nil > else if areEqual(a, b)  return a > for i := 0; i < len(b); i++  a = remove(a, b[i]) > var c = make([]int, len(a)) return writeData(a, c) > func remove(arr []int, elem int) []int  var idx int if isEmpty(arr, elem)  for ; idx < len(arr); idx++  if arr[idx] == elem  break > > > else  return arr > arr[idx] = arr[len(arr)-1] return remove(arr[:len(arr)-1], elem) > func isEmpty(arr []int, elem int) bool  for i := 0; i < len(arr); i++  if arr[i] == elem  return true > > return false > func areEqual(a, b []int) bool  if len(a) != len(b)  return false > for i, elem := range a  if elem != b[i]  return false > > return true > func writeData(a, b []int) []int  for i := 0; i < len(a); i++  b[i] = a[i] > return b >

Пример ошибок теста
#1
Expected
<[]int | len:14, cap:14>: [-14, -10, -10, -9, -8, -8, -7, -7, -6, -1, 6, 18, 18, 20]
to equal
<[]int | len:14, cap:16>: [-8, -7, 18, -10, 20, -6, -10, -9, -14, 18, 6, -7, -8, -1]

Примечательна ошибка 3, вроде бы все тоже самое, емкость одинаковая, но да, вывод по разному. Даже не знаю куда копать

Добавлено через 11 минут
Немного оптимизировал код, теперь пару функций вот такие:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
func remove(arr []int, elem int) []int  isEmp, idx := isEmpty(arr, elem) if !isEmp  return arr > arr[idx] = arr[len(arr)-1] return remove(arr[:len(arr)-1], elem) > func isEmpty(arr []int, elem int) (bool, int)  for i := 0; i < len(arr); i++  if arr[i] == elem  return true, i > > return false, 0 >

Добавлено через 48 минут
Решил сам, но решение не принимает, видимо проблема с тестом.
Все тестовые примеры на которых программа спотыкалась проверял отдельно в поле для тестов codewars, а также у себя на рабочей машине. Все работало

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
func ArrayDiff(a, b []int) []int  fmt.Println("A: ", a) fmt.Println("B: ", b) if len(b) == 0  return a > else if len(a) == 0  return nil > else if areEqual(a, b)  return a > a = uniqeElems(a, b) var c = make([]int, lenCountWithoutZeros(a)) for i, j := 0, 0; i < len(a); i++  if a[i] != 0  c[j] = a[i] j++ > > return c > func areEqual(a, b []int) bool  if len(a) != len(b)  return false > for i, elem := range a  if elem != b[i]  return false > > return true > func uniqeElems(a, b []int) []int  for i := 0; i < len(b); i++  for j := 0; j < len(a); j++  if b[i] == a[j]  a[j] = 0 > > > return a > func lenCountWithoutZeros(a []int) int  var count int for i := 0; i < len(a); i++  if a[i] != 0  count++ > > return count >

Удалить элемент из массива по значению

Хранить слайс структур по значению — это плохо. Они туда копируются каждый раз.

И это не придирка, так у тебя будет «течь» память.

Представим что ты добавил 1000 элементов в []Hello, слайс ссылается на массив где хранятся эти 1000 элементов (а реально capacity может быть и больше необходимого и тогда там будут лежать new(Hello) ), но потом ты решил удалить 500, и как бы ты не сдвигал «окошко» слайса в нижележащем массиве всегда будут храниться либо твои «удаленные» структуры, либо тебе придется их перезатирать элементами new(Hello) (тогда удаленные заберет сборщик мусора) и все равно это жрет память как для cap(list) элементов. Пока, конечно, ты снова не добавишь 500 элементов и тогда они реально перезатрутся и сборщик мусора сможет их забрать. И если у тебя «жирная» структура с большим количеством полей и/или вложенными структурами (по ссылке или копией), каналами и прочим то все это тоже будет висеть в памяти, пока не перезатрешь новыми элементами.

Правильный подход будет хранить слайс указателей, они хотя бы жрут память независимо от количества полей и их типа в структуре.

type Hello struct <> . var list []*Hello . hello1 := &Hello<> hello2 := &Hello<> hello3 := &Hello<> list = append(list, hello1, hello2, hello3) 

Тогда функция для удаления

func Remove(list []*Hello, item *Hello) []*Hello < for i, v := range list < if v == item < copy(list[i:], list[i+1:]) list[len(list)-1] = nil // обнуляем "хвост" list = list[:len(list)-1] >> return list > 

Причем, сравнение v == item отработает правильно даже если это два разных указателя на одну и ту же структуру.

И удалять можно как

list = Remove(list, hello2) 

Обрати внимание, что слайс нужно переприсвоить как и в случае с добавлением.

По поводу обнуления хвоста. Если ты просто уменьшишь длину слайса, то в нижелещащем массиве все равно останется ссылка на структуру, которая тебе уже не нужна, и сборщик мусора не сможет ее забрать.

click fraud protection

Срез в Go — это тип данных, в котором хранится набор упорядоченных данных одного типа. Срезы очень похожи на массив. Однако, в отличие от массивов, срезы являются динамическими и не имеют фиксированной длины. Имейте в виду, что, несмотря на длину, срезы сохраняют другие свойства массива Golang, в том числе тип.

В этой статье мы рассмотрим, как удалить элемент из фрагмента.

Голанг Создать срез

Мы можем создать срез в Go, указав тип данных элементов, которые он будет содержать. Затем мы можем заключить элементы массива в пару фигурных скобок.

Пример кода ниже показывает, как создать слайс в Go:

упаковка основной
функция () <
ломтик := [] нить < "а" , "б" , "с" , "д" >
>

После объявления среза мы можем выполнять такие действия, как обновление элементов по определенному индексу, доступ к элементам, добавление дополнительных элементов и многое другое. Ознакомьтесь с нашим руководством по фрагментам Golang, чтобы узнать больше.

Голанг Удалить элемент

Прежде чем мы обсудим, как удалить элемент из слайса, давайте обсудим, как мы можем создать вложенный слайс из основного слайса. Это связано с тем, что важно понимать, как удалить элемент из среза.

Мы можем создать подсрез, используя нотацию индексации. Например, если мы хотим создать подсрез, состоящий из значений от индекса 2 до 7, мы можем сделать:

новый_срез := old_slice [ 2 : 7 ]

Приведенный выше синтаксис захватывает элементы с индексами от 2 до 7 из старого слайса и создает новый слайс.

Если вы хотите создать подсрез от индекса 0 до целевого индекса, мы можем сделать:

новый_срез := old_slice [: 5 ]

Приведенный выше синтаксис возьмет элементы от индекса 0 до индекса 5 и создаст новый срез.

Теперь, когда у нас есть процесс создания подфрагмента из слайса, мы можем приступить к изучению того, как удалить элемент из слайса.

Сохранить порядок фрагментов

Предположим, у нас есть срез, содержащий элементы, как показано ниже:

Если мы хотим удалить элемент из среза и при этом сохранить порядок, мы сдвигаем позиции элементов после элемента, который мы хотим удалить, влево с коэффициентом один.

Мы можем выразить приведенный выше синтаксис как:

сдвиг Лен ( а ) — я — 1

Где a представляет срез, а i — индекс элемента, который мы хотим удалить.

Пример кода показан ниже:

упаковка основной
импорт «ФМТ»
функция основной () <
ломтик := [] нить < "а" , "б" , "с" , "д" , "е" , "ф" >
показатель := 1
копировать ( ломтик [ показатель :], ломтик [ показатель + 1 :]) // сдвигаем значения после индекса с коэффициентом 1
ломтик [ Лен ( ломтик ) — 1 ] = «» // удалить элемент
ломтик = ломтик [: Лен ( ломтик ) — 1 ] // обрезать срез
ФМТ . Распечатать ( ломтик )
>

Приведенный выше код удалит элемент с индексом 0. Результирующий срез выглядит следующим образом:

Игнорировать порядок нарезки

Если резервирование порядка фрагментов не имеет решающего значения, мы можем использовать код, как показано ниже:

упаковка основной
импорт «ФМТ»
функция основной () <
ломтик := [] нить < "а" , "б" , "с" , "д" , "е" , "ф" >
показатель := 1
ломтик [ показатель ] = ломтик [ Лен ( ломтик ) — 1 ] // копируем последний элемент в index, который мы хотим удалить
ломтик [ Лен ( ломтик ) — 1 ] = «» // удалить элемент
ломтик = ломтик [: Лен ( ломтик ) — 1 ]
ФМТ . Распечатать ( ломтик )
>

Приведенный выше код удаляет элемент по указанному индексу. Однако он не сохраняет порядок среза, как показано в выходных данных ниже:

Это потому, что этот метод заменяет удаленный элемент элементом с последним индексом.

Заключение

В этом руководстве мы рассмотрели основы работы со слайсами и то, как удалить элемент из слайса с сохранением порядка слайсов и без него.

Как удалить элемент из массива golang

Запись: and-semakin/mytetra_data/master/base/160520373715n0kd27no/text.html на raw.githubusercontent.com

a = append(a[0:2], a[3:]. )

fmt.Println(a) // [1 2 4 5 6 7]

В данном примере . (многоточие) после слайса означает распаковку. Это необходимо, потому что функция append ожидает, что элементы для вставки будут переданы в нее поотдельности.

  • Настроить переменные окружения для Golang в Fish
  • Установить godoc и golint при помощи go
  • Типы данных в Golang
  • Булевый тип данных в Golang
  • Строки в Golang
  • Числа в Golang
  • Объявление переменных в Golang
  • Арифметические операции в Golang
  • Чтение данных с консоли в Golang
  • Вывод данных на консоль в Golang
  • Комментарии в Golang
  • Константы в Golang
  • iota для объявления констант в Golang
  • Условные выражения (сравнения) в Golang
  • Условная конструкция в Golang
  • Конструкция switch/case в Golang
  • Циклы в Golang
  • Форматированный вывод в Golang
  • Массивы в Golang
  • Срезы (слайсы, slice) в Golang
  • Удаление элемента из слайса при помощи append в Golang
  • Функции в Golang
  • Области видимости в Golang

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *