2009-11-24 62 views
31

Nếu tôi có một mảng có 12 phần tử và tôi muốn một mảng mới với các phần tử đầu tiên và thứ 12. Ví dụ, nếu mảng của tôi trông như thế này:Tập hợp các mảng trong C#

__ __ __ __ __ __ __ __ __ __ __ __ 
a b c d e f g h i j k l 
__ __ __ __ __ __ __ __ __ __ __ __ 

Tôi muốn một trong hai biến nó hoặc tạo một mảng mới trông giống như

__ __ __ __ __ __ __ __ __ __ 

b c d e f g h i j k 
__ __ __ __ __ __ __ __ __ __ 

Tôi biết tôi có thể làm điều đó bằng cách duyệt qua chúng. Tôi đã chỉ tự hỏi nếu có một cách sạch hơn được xây dựng vào C#.

** CẬP NHẬT ĐỂ TÌM MỘT LOẠI. Đã thay đổi 10 thành phần thành 12 phần tử.

+0

Không phải là "j" phần tử thứ 10 trong mảng không? Hoặc bạn có nghĩa là các yếu tố đầu tiên và cuối cùng? –

Trả lời

66

LINQ là bạn của bạn. :)

var newArray = oldArray.Skip(1).Take(oldArray.Length - 2).ToArray(); 

Hơi kém hiệu quả hơn bằng tay tạo mảng và lặp lại trên nó tất nhiên, nhưng đến nay đơn giản ...

Phương pháp hơi lengithier sử dụng Array.Copy là như sau.

var newArray = new int[newArray.Count - 2]; 
Array.Copy(oldArray, 1, newArray, 0, newArray.Length); 
+0

Tôi thực sự thích câu trả lời ban đầu của bạn. LINQ đã là bạn của tôi cho đôi khi. Tôi chỉ không bao giờ sử dụng bỏ qua và lấy. Cảm ơn. – LJM

+0

@L. Moser: Không sao cả - cũng đã thay đổi. :) Và vâng, tôi nghĩ rằng tôi khám phá ra một phương pháp LINQ hữu ích mới mỗi tuần hoặc lâu hơn. – Noldorin

+3

Trong khi LINQ là tiện dụng, nó là MUCH ít performant – Mario

5

Bạn có thể thực hiện việc này với Array.Copy hoặc LINQ.

var letters = string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i" }; 

int length = letters.Length - 2; 
var items = new string[length]; 
Array.Copy(letters, 1, items, 0, length); 
// or 
var items = letters.Skip(1).Take(length).ToArray(); 
1
string[] s = initialize the array... 

var subset = s.Skip(1).Take(s.Length - 2).ToArray(); 
+0

giải pháp thú vị – JohnIdol

2

Array.Copy() sẽ làm điều đó cho bạn, nhưng bạn vẫn phải tạo mảng mới của bạn với kích thước chính xác của nó.

30

LINQ là tất cả tốt đẹp và hợp thời, nhưng nếu bạn đang tìm kiếm một 1-liner bạn chỉ có thể nhét vào chức năng tiện ích của riêng bạn:

static class ArrayUtilities 
{ 
    // create a subset from a range of indices 
    public static T[] RangeSubset<T>(this T[] array, int startIndex, int length) 
    { 
     T[] subset = new T[length]; 
     Array.Copy(array, startIndex, subset, 0, length); 
     return subset; 
    } 

    // create a subset from a specific list of indices 
    public static T[] Subset<T>(this T[] array, params int[] indices) 
    { 
     T[] subset = new T[indices.Length]; 
     for (int i = 0; i < indices.Length; i++) 
     { 
      subset[i] = array[indices[i]]; 
     } 
     return subset; 
    } 
} 

Vì vậy, sau đó bạn có thể làm như sau:

 char[] original = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; 

     // array containing 'b' - 'f' 
     char[] rangeSubset = original.RangeSubset(1, original.Length - 2); 

     // array containing 'c', 'd', and 'f' 
     char[] specificSubset = original.Subset(2, 3, 5); 
+2

Tôi thực sự thích giải pháp này. –

0

Nếu bạn muốn tránh lập chỉ mục mảng theo cách thủ công. Đừng cố gắng để kéo yêu cầu rằng bất cứ nơi nào dù:

var newArray = oldArray.Skip(1).Reverse().Skip(1).Reverse().ToArray() 
+0

Điều này dường như không làm giảm phần tử cuối cùng. –

+0

cảm ơn @NathanTuggy, quên mất điều đó. – Tobias

2

Bạn có thể sử dụng ArraySegment<T> cấu trúc như sau:

var arr = new[] { 1, 2, 3, 4, 5 }; 
var offset = 1; 
var count = 2; 
var subset = new ArraySegment<int>(arr, offset, count) 
      .ToArray(); // output: { 2, 3 } 

Kiểm tra ở đây cho một extension method mà làm cho sử dụng của nó thậm chí còn dễ dàng hơn.

Các vấn đề liên quan