Как удалить элемент из массива в D
Объединение элемента x
в массив items
легко в D, это как если бы это был список массивов:
arr ~= x;
но как удалить элемент в индексе i
из items
?
(Предостережение: если я удалю элемент и добавлю новый элемент, массив не должен быть перераспределен. Таким образом, простой срез не будет работать.)
Обновление:
На основании ответа CyberShadow об использовании assumeSafeAppend
, я написал этот код:
static void removeAt(T)(ref T[] arr, size_t index)
{
foreach (i, ref item; arr[index .. $ - 1])
item = arr[i + 1];
arr = arr[0 .. $ - 1];
arr.assumeSafeAppend();
}
Однако проблема возникает, когда у вас есть что-то вроде:
auto superArr = [0, 1, 2, 3, 4]; //Must not be modified
auto arr = superArr[0 .. $ - 1];
writeln(superArr);
arr.removeAt(0); //Should copy the slice and modify the copy
writeln(superArr); //but obviously doesn't
Базовый массив среза должен быть не изменен, если элемент удален из среза; вместо этого нужно скопировать фрагмент.
Но у меня нет способа узнать, является ли массив срезом большего массива... так что это не работает.
Любые предложения?
Ответы
Ответ 1
(Предостережение: если я удалю элемент и добавлю новый элемент, массив не должен быть перераспределен. Таким образом, простой срез не будет работать.)
Функция assumeSafeAppend
сообщит, что среда выполнения не перераспределяет массив при добавлении к нему (т.е. это подтверждение от пользователя что нет других фрагментов, которые могут быть сжаты добавлением).
remove
из std.algorithm делает удаление на месте. Если вы используете std.container, там также Array.linearRemove
.
Ответ 2
Копирование моего ответа на digitalmars.D(спасибо за пересылку):
Как уже упоминалось, std.algorithm.remove может помочь. Возможно, вам захочется взглянуть на три из его возможностей, в частности: (a) удалить несколько смещений за один проход, например. remove (a, 0, 4) удаляет первый и пятый элементы, (b) вы можете удалить поддиапазоны, например. remove (a, кортеж (1, 3)) удаляет второй-четвертый элемент и (c), если вам не нужен порядок, в котором элементы остаются после удаления, вы можете захотеть взглянуть на неустойчивое удаление, что значительно меньше работа.
Андрей
Ответ 3
Хорошо, если порядок не имеет значения, вы можете скопировать последний элемент в место удаления, а затем уменьшить длину массива на единицу.
Ответ 4
Если вы просто хотите удалить первый или последний элементы, используйте срезы:
array = array [1..$]
array = array [0..$-1]
Или общий способ, который работает и для среднего:
array = array [0..unlucky] ~ array [unlucky+1..$]
Если элементы не являются базовыми элементами, такими как structs, floats, ints, тогда массивы являются неявно массивами указателей, и это эффективная операция.
Ответ 5
Нет автоматизированного способа сделать это, вам нужно будет перетасовать элементы массива вдоль, reset.length и затем соединить.