2012-02-17 35 views
5

Trong perl, hàm ghép nối trả về một mảng các mục mới từ một mảng hiện có và đồng thời loại bỏ các mục này khỏi mảng hiện có.Ghép nối trên bộ sưu tập

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

@newarray bây giờ sẽ chứa 250 hồ sơ từ @oldarray@oldarray là 250 hồ sơ ít hơn.

Có tương đương với các lớp thu thập C# tức là Array, List, Queue, Stack với chức năng tương tự không? Cho đến nay tôi đã chỉ nhìn thấy các giải pháp mà hai bước được yêu cầu (return + remove).

Update - không có chức năng tồn tại vì vậy tôi đã thực hiện một phương pháp extensio để hỗ trợ chức năng 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; 
} 

Với bài kiểm tra đơn vị sau đây - mà thành công:

[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

Không có tương đương trực tiếp trong các lớp thu thập .NET. Bạn có thể, tất nhiên, viết phương pháp trợ giúp của riêng bạn mà trả lại + loại bỏ. Bạn định sử dụng phương pháp này như thế nào? Có lẽ có một cách C# ish hơn để làm điều đó thay vì cố gắng để thực hiện một mô hình từ Perl. – dtb

+1

Cảm ơn bạn - Tôi đã tạo một phương thức mở rộng để thêm chức năng ghép nối vào danh sách - điều này cũng có thể được tổng quát hơn để hỗ trợ IEnumerables. – SADeveloper

+0

Bạn có thể thay thế 'Source.Skip (Bắt đầu) .Take (Size) .ToList ()' by 'Source.GetRange (Bắt đầu, Kích thước)'. – Henrik

Trả lời

0

Có duy nhất là Stack.Pop()Queue.Dequeue() sẽ trả lại và xóa một mục nhưng không phải nhiều mục.

Nếu bạn cần hành vi này, bạn phải viết nó trên một của bạn, nhưng có lẽ bạn chỉ có thể quấn một trong những điều trên. Nhưng bạn nên xác định điều gì sẽ xảy ra nếu người dùng xác định số lớn hơn các thành phần có sẵn hoặc số không hoặc ít hơn.

2

Bạn có thể triển khai phương pháp Splice với tiện ích mở rộng. Phương thức này đơn giản nhận được một phạm vi (là một bản sao của đối tượng được tham chiếu trong danh sách), sau đó nó loại bỏ các đối tượng khỏi danh sách.

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

Nếu số phần tử ghép lớn hơn thì số lượng phần tử trong danh sách rồi phương thức GetRange() và RemoveRange() ném một ngoại lệ. Giải pháp tốt hơn là sử dụng Skip() và Take() và kiểm tra Kích thước danh sách:

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; 
     } 
    } 
Các vấn đề liên quan