在D中将元素x
连接到数组items
很容易,就像它是一个数组列表一样:
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
如果从切片中删除元素,则应修改切片的基础数组 not ;相反,需要复制切片。
但我无法知道数组是否是更大数组的切片......所以这不起作用。
有什么建议吗?
答案 0 :(得分:20)
在digitalmars.D上复制我的答案(感谢转发):
如前所述,std.algorithm.remove可以提供帮助。您可能希望特别关注其中的三个功能:(a)在一次传递中删除多个偏移,例如: remove(a,0,4)删除第一个和第五个元素,(b)你可以删除子范围,例如remove(a,tuple(1,3))删除第二个到第四个元素,(c)如果你不关心删除后剩下元素的顺序你可能想要查看不稳定的删除,这相当大减少工作量。
安德烈
答案 1 :(得分:12)
(警告:如果我删除一个元素然后添加一个新元素,则不能重新分配数组 。所以一个简单的切片将不起作用。)
assumeSafeAppend
函数会告诉运行时在追加数组时不要重新分配数组(即来自用户的肯定是没有其他切片可能会被追加踩踏)。
remove
会就地删除。如果您使用的是std.container,那么还会Array.linearRemove
。
答案 2 :(得分:3)
如果顺序不重要,您可以将最后一个元素复制到删除位置,然后将数组长度减少一个。
答案 3 :(得分:1)
如果您只想删除第一个或最后一个元素,请使用切片:
array = array [1..$]
array = array [0..$-1]
或者也适用于中间的一般方式:
array = array [0..unlucky] ~ array [unlucky+1..$]
如果元素不是基本元素,例如结构,浮点数,整数,则数组是隐式指针数组,这是一种有效的操作。
答案 4 :(得分:-6)
没有自动执行此操作的方法,您必须随机播放数组项,重置.length然后连接。