Сращивание по коллекциям - PullRequest
5 голосов
/ 17 февраля 2012

В perl функция splice возвращает новый массив элементов из существующего массива и одновременно удаляет эти элементы из существующего массива.

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

@newarray теперь будет содержать 250 записей из @oldarray, а @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");

  }
}

Ответы [ 3 ]

3 голосов
/ 20 апреля 2016

Вы можете реализовать метод 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;
      }
  }
}
0 голосов
/ 20 июля 2017

Если количество склеенных элементов больше, чем количество элементов в списке, то методы 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;
      }
    }
0 голосов
/ 17 февраля 2012

Существует только Stack.Pop() и Queue.Dequeue(), которые возвращают и удаляют один элемент, но не несколько.

Если вам нужно такое поведение, вы должны написать его на своем, но, возможно, вы можете просто обернуть один из вышеперечисленных. Но вы должны определить, что произойдет, если пользователь определит большее число, чем доступные элементы, или число ноль или меньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...