在perl中,splice函数从现有数组返回一个新的项目数组,同时从现有数组中删除这些项目。
my @newarry = splice @oldarray, 0, 250;
@newarray
现在将包含来自@oldarray
的250条记录,而@oldarray
则会减少250条记录。
是否有C#集合类的等价物,即Array,List,Queue,Stack具有类似的功能?到目前为止,我只看到了需要两个步骤的解决方案(返回+删除)。
更新 - 没有功能存在,所以我实现了一个extensio方法来支持Splice功能:
public static List<T>Splice<T>(this List<T> Source, int Start, int Size)
{
List<T> retVal = Source.Skip(Start).Take(Size).ToList<T>();
Source.RemoveRange(Start, Size);
return retVal;
}
使用以下单元测试 - 成功:
[TestClass]
public class ListTest
{
[TestMethod]
public void ListsSplice()
{
var lst = new List<string>() {
"one",
"two",
"three",
"four",
"five"
};
var newList = lst.Splice(0, 2);
Assert.AreEqual(newList.Count, 2);
Assert.AreEqual(lst.Count, 3);
Assert.AreEqual(newList[0], "one");
Assert.AreEqual(newList[1], "two");
Assert.AreEqual(lst[0], "three");
Assert.AreEqual(lst[1], "four");
Assert.AreEqual(lst[2], "five");
}
}
答案 0 :(得分:3)
您可以使用扩展名实现Splice方法。此方法只获取一个范围(它是列表中引用对象的副本),然后从列表中删除对象。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpliceExample
{
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> subset = numbers.Splice(3, 3);
Console.WriteLine(String.Join(", ", numbers)); // Prints 1, 2, 3, 7, 8, 9
Console.WriteLine(String.Join(", ", subset)); // Prints 4, 5, 6
Console.ReadLine();
}
}
static class MyExtensions
{
public static List<T> Splice<T>(this List<T> list, int index, int count)
{
List<T> range = list.GetRange(index, count);
list.RemoveRange(index, count);
return range;
}
}
}
答案 1 :(得分:0)
只有Stack.Pop()
和Queue.Dequeue()
会返回并删除一个项目,但不会删除多个项目。
如果你需要这种行为,你必须把它写在你的行为上,但也许你可以简单地包装上面的一个。但是,如果用户定义的数字大于可用元素或者数字为零或更少,则应定义会发生什么。
答案 2 :(得分:0)
如果拼接元素的数量大于列表中元素的数量,则GetRange()和RemoveRange()方法会抛出异常。更好的解决方案是使用Skip()和Take()并检查List size:
public static class ListExtension
{
public static List<T> Splice<T>(this List<T> source, int start, int size)
{
var items = source.Skip(start).Take(size).ToList<T>();
if (source.Count >= size)
source.RemoveRange(start, size);
else
source.Clear();
return items;
}
}