2013-09-07 63 views
9

Tôi có một 2D mảng như thế này:Làm thế nào để tìm kiếm trong mảng 2D bằng LINQ [version2]

string[,] ClassNames = 
{ 
    {"A","Red"}, 
    {"B","Blue"}, 
    {"C","Pink"}, 
    {"D","Green"}, 
    {"X","Black"}, 
}; 

tôi tìm kiếm ClassName trong 1nd cột bằng cách cho tuyên bố và trở ColorName trong 2nd cột như sau:

string className = "A"; 
string color = "Black"; 
for (int i = 0; i <= ClassNames.GetUpperBound(0); i++) 
{ 
    if (ClassNames[i, 0] == className) 
    { 
     color = ClassNames[i, 1]; 
     Response.Write(color); 
     break; 
    } 
} 

tôi muốn sử dụng LINQ thay vì cho tuyên bố để có được những màu bởi className. cách chuyển đổi câu lệnh trên thành LINQ.

+2

Mảng 2D của bạn trông giống như nó phải là từ điển thay thế? –

+0

Mảng 2D thực chất là một công cụ 'c', trong C# chúng ta nên sử dụng các cấu trúc/lớp bộ sưu tập khác. –

Trả lời

11

Bạn có thể sử dụng phương thức để tạo chuỗi các số nguyên và sau đó sử dụng LINQ để truy vấn điều đó.

Something như thế này sẽ làm việc:

string color = Enumerable 
    .Range(0, ClassNames.GetLength(0)) 
    .Where(i => ClassNames[i, 0] == className) 
    .Select(i => ClassNames[i, 1]) 
    .FirstOrDefault() ?? "Black"; 

Hoặc trong cú pháp truy vấn:

string color = 
    (from i in Enumerable.Range(0, ClassNames.GetLength(0)) 
    where ClassNames[i, 0] == className 
    select ClassNames[i, 1]) 
    .FirstOrDefault() ?? "Black"; 

Hoặc có lẽ chuyển đổi mảng đến một Dictionary<string, string> đầu tiên:

Dictionary<string, string> ClassNamesDict = Enumerable 
    .Range(0, ClassNames.GetLength(0)) 
    .ToDictionary(i => ClassNames[i, 0], i => ClassNames[i, 1]); 

Và sau đó bạn có thể truy vấn dễ dàng hơn nhiều:

color = ClassNamesDict.ContainsKey(className) 
     ? ClassNamesDict[className] 
     : "Black"; 

Tạo từ điển trước và sau đó truy vấn từ điển sẽ hiệu quả hơn nhiều nếu bạn phải thực hiện nhiều truy vấn như thế này.

+0

'??' là gì? –

+0

@SamieyMehdi Đó là [toán tử kết hợp rỗng] (http://msdn.microsoft.com/en-us/library/ms173224.aspx). Về cơ bản nó có nghĩa là 'nếu giá trị bên trái là null, hãy sử dụng giá trị bên phải'. Lưu ý rằng điều này chỉ hoạt động đối với các kiểu tham chiếu hoặc không có giá trị. Nếu mảng thực của bạn là 'int [,]', bạn sẽ phải đưa kết quả vào một '(int?)' Trong mệnh đề select để làm việc đó. –

3

Ở đây bạn là:

color = ClassNames.Cast<string>() 
        .Select((x, i) => new { x, i }) 
        .GroupBy(x => x.i/2, (k,x) => x.Select(y => y.x)) 
        .Where(g => g.First() == className) 
        .Select(x => x.Last()).First(); 

Nhưng phải trung thực, Tôi sẽ không bao giờ sử dụng LINQ để làm điều đó. Nó kém hiệu quả, ít đọc được và tệ hơn để duy trì. Bạn nên xem xét sử dụng các vòng for hiện tại hoặc thay đổi cấu trúc dữ liệu của mình, thành List<CustomClass> hoặc Dictionary<string, string> thay vì string[,].

+0

không hoạt động, lỗi là: Trình tự không chứa các phần tử –

+1

Bạn sẽ nhận được lỗi đó khi không có phần tử nào phù hợp. Tôi đã thử nghiệm nó với đầu vào mẫu của bạn và trả về '" Đỏ "'. – MarcinJuraszek