2008-09-25 82 views
31

Cách nhanh nhất để khởi tạo một mảng kích thước động trong C# mà bạn biết là gì?C# Khởi tạo mảng - với giá trị không mặc định

Đây là tốt nhất mà tôi có thể đưa ra

private bool[] GetPageNumbersToLink(IPagedResult result) 
{ 
    if (result.TotalPages <= 9) 
     return new bool[result.TotalPages + 1].Select(b => true).ToArray(); 

    ... 

Trả lời

34

sử dụng Enumerable.Repeat

Enumerable.Repeat(true, result.TotalPages + 1).ToArray() 
+1

Bây giờ chỉ là trơn! – Rob

+12

Tôi nghĩ rằng lưu ý hiệu suất của Nigel bảo đảm một đề cập đến - http://stackoverflow.com/questions/136836/c-array-initialization-with-non-default-value/1051227#1051227 – CrimsonX

+9

Tôi không thể tin rằng mọi người upvote cho một cái gì đó nên 'mờ' (theo ý kiến ​​của tôi) và tốn kém cho một thao tác đơn giản như điền vào một mảng. 'var arr = loại mới [10]; for (int i = 0; i Aidiakapi

0

chưa được kiểm tra, nhưng có thể bạn chỉ cần làm điều này?

return result.Select(p => true).ToArray(); 

Bỏ qua phần "mới bool []"?

+1

chỉ khi IPagedResult: IEnumerable

5

Tôi thực sự sẽ đề nghị này:

return Enumerable.Range(0, count).Select(x => true).ToArray(); 

Bằng cách này bạn chỉ bố trí một mảng. Đây thực chất là cách ngắn gọn hơn để thể hiện:

var array = new bool[count]; 

for(var i = 0; i < count; i++) { 
    array[i] = true; 
} 

return array; 
+1

Hoặc thậm chí mới bool [count ] .Chọn (x => true) .ToArray() – BjartN

+2

Điều đó sẽ vẫn phân bổ hai mảng. –

13

EDIT: làm người nhận xét đã chỉ ra, triển khai ban đầu của tôi không hoạt động. Phiên bản này hoạt động nhưng khá un-slick được dựa trên một vòng lặp for.

Nếu bạn sẵn sàng để tạo ra một phương pháp mở rộng, bạn có thể thử này

public static T[] SetAllValues<T>(this T[] array, T value) where T : struct 
{ 
    for (int i = 0; i < array.Length; i++) 
     array[i] = value; 

    return array; 
} 

và sau đó gọi nó như thế này

bool[] tenTrueBoolsInAnArray = new bool[10].SetAllValues(true); 

Là một thay thế, nếu bạn hài lòng với có một lớp học treo quanh, bạn có thể thử một cái gì đó như thế này

public static class ArrayOf<T> 
{ 
    public static T[] Create(int size, T initialValue) 
    { 
     T[] array = (T[])Array.CreateInstance(typeof(T), size); 
     for (int i = 0; i < array.Length; i++) 
      array[i] = initialValue; 
     return array; 
    } 
} 

mà bạn có thể gọi là

bool[] tenTrueBoolsInAnArray = ArrayOf<bool>.Create(10, true); 

Không chắc chắn tôi thích, mặc dù tôi sử dụng nhiều phương pháp mở rộng và rất nhiều.

+0

Tôi không tin rằng SetAllValues ​​của bạn sẽ hoạt động: Trong biểu thức lambda của bạn, x không được truyền theo tham chiếu, do đó gán giá trị cho nó không thay đổi giá trị được lưu trữ trong mảng. –

+0

Vâng, bạn hoàn toàn đúng. Tôi đã đề cập đến tôi đã không thực sự biên dịch nó mà có thể đã cho thấy rằng khá sai lầm tiểu học. Tôi thay thế các ForEach với một vòng lặp đơn giản và hoạt động tốt, nhưng nó không slick như người hỏi yêu cầu. –

+1

Ngoài ra, phương pháp mở rộng của bạn có chữ ký ngụ ý rằng nó sẽ trả về một mảng mới, nhưng nó sửa đổi mảng ban đầu và trả về thay vào đó. Hình thức xấu. –

70

Nếu bằng 'slickest' bạn có nghĩa là nhanh nhất, tôi sợ rằng Enumerable.Repeat có thể 20x chậm hơn so với một cho vòng lặp. Xem http://dotnetperls.com/initialize-array:

Initialize with for loop:    85 ms [much faster] 
Initialize with Enumerable.Repeat: 1645 ms 

Vì vậy, sử dụng phương pháp() SetAllValues ​​Dotnetguy của.

+11

+1 cho ghi chú hiệu suất. – AMissico

1

Nhiều lần bạn muốn khởi tạo các tế bào khác nhau với các giá trị khác nhau:

public static void Init<T>(this T[] arr, Func<int, T> factory) 
{ 
    for (int i = 0; i < arr.Length; i++) 
    { 
     arr[i] = factory(i); 
    } 
} 

Hoặc trong hương vị nhà máy:

public static T[] GenerateInitializedArray<T>(int size, Func<int, T> factory) 
{ 
    var arr = new T[size]; 
    for (int i = 0; i < arr.Length; i++) 
    { 
     arr[i] = factory(i); 
    } 
    return arr; 
} 
Các vấn đề liên quan