集合上的拼接

本文关键字:拼接 集合 | 更新日期: 2023-09-27 18:25:07

在perl中,splice函数从现有数组中返回一个新的项数组,同时从现有数组删除这些项。

my @newarry = splice @oldarray, 0, 250;

@newarray现在将包含来自@oldarray的250个记录,而@oldarray少了250个记录。

C#集合类(数组、列表、队列、堆栈)是否有类似的函数?到目前为止,我只看到了需要两个步骤(return+remove)的解决方案。

更新-不存在任何功能,所以我实现了一个扩展方法来支持拼接功能:

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");
  }
}

集合上的拼接

您可以实现带有扩展的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;
      }
  }
}

只有Stack.Pop()Queue.Dequeue()会返回和删除一个项目,但不会删除多个项目。

如果你需要这种行为,你必须把它写在你的行为上,但也许你可以简单地包装上面的一个。但是,您应该定义如果用户定义的元素数量大于可用元素数量,或者数量为零或更少,会发生什么。

如果拼接的元素数量大于列表中的元素数量,则GetRange()和RemoveRange(()方法会抛出异常。更好的解决方案是使用Skip()和Take()并检查列表大小:

    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;
      }
    }