如何从D中删除数组中的元素

时间:2011-05-16 08:53:34

标签: arrays d

在D中将元素x连接到数组items很容易,就像它是一个数组列表一样:

arr ~= x;

但我如何从i 删除索引items的元素?

(警告:如果我删除一个元素然后添加一个新元素,则不能重新分配数组 。所以一个简单的切片将不起作用。)


更新

根据Cyber​​Shadow关于使用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 ;相反,需要复制切片。

但我无法知道数组是否是更大数组的切片......所以这不起作用。

有什么建议吗?

5 个答案:

答案 0 :(得分:20)

在digitalmars.D上复制我的答案(感谢转发):

如前所述,std.algorithm.remove可以提供帮助。您可能希望特别关注其中的三个功能:(a)在一次传递中删除多个偏移,例如: remove(a,0,4)删除第一个和第五个元素,(b)你可以删除子范围,例如remove(a,tuple(1,3))删除第二个到第四个元素,(c)如果你不关心删除后剩下元素的顺序你可能想要查看不稳定的删除,这相当大减少工作量。

安德烈

答案 1 :(得分:12)

  

(警告:如果我删除一个元素然后添加一个新元素,则不能重新分配数组 。所以一个简单的切片将不起作用。)

assumeSafeAppend函数会告诉运行时在追加数组时不要重新分配数组(即来自用户的肯定是没有其他切片可能会被追加踩踏)。

来自std.algorithm

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然后连接。