2012-02-17 36 views
5

W perlu funkcja splicingu zwraca nową tablicę elementów z istniejącej tablicy i jednocześnie usuwa te elementy z istniejącej tablicy.Splice na kolekcjach

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

@newarray będzie teraz zawierać 250 rekordów z @oldarray i @oldarray 250 rekordy mniej.

Czy istnieje odpowiednik dla klas kolekcji C#, np. Array, List, Queue, Stack z podobną funkcją? Do tej pory widziałem tylko rozwiązania, w których wymagane są dwa kroki (return + remove).

Update - brak funkcjonalności istnieje więc wprowadziliśmy metodę extensio wspierania funkcji 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; 
} 

z następującymi testów jednostkowych - który udaje:

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

    } 
} 
+1

Brak bezpośrednich odpowiedników w klasach kolekcji .NET. Można oczywiście napisać własną metodę pomocy, która zwraca + usuwa. Jak zamierzasz korzystać z tej metody? Być może istnieje więcej C# ish sposobu to zrobić, zamiast próbować nosić wzór z Perl. – dtb

+1

Dziękuję - stworzyłem metodę rozszerzenia, aby dodać funkcję składania do list - może to być dodatkowo uogólnione do obsługi IEnumerables. – SADeveloper

+0

Można zamienić 'Source.Skip (Start) .Take (Size) .ToList ()' od 'Source.GetRange (Start, Size)'. – Henrik

Odpowiedz

0

Jest tylko Stack.Pop() i Queue.Dequeue(), która zwróci i usunie jeden element, ale nie wiele.

Jeśli potrzebujesz tego zachowania, musisz je zapisać na swoim, ale może po prostu owinąć jeden z powyższych. Ale powinieneś zdefiniować, co się stanie, jeśli użytkownik zdefiniuje większą liczbę niż dostępne elementy lub liczbę zero lub mniej.

2

Można zaimplementować metodę Splice z rozszerzeniem. Ta metoda po prostu otrzymuje zakres (który jest kopią obiektu przywoływanego na liście), a następnie usuwa obiekty z listy.

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

Jeżeli liczba składanych elementów jest większe od liczby elementów na liście następnie GetRange() i RemoveRange() w rzut wyjątek. Lepszym rozwiązaniem jest użycie Pomiń() i Take() i sprawdź rozmiar listy:

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; 
     } 
    } 
Powiązane problemy