2013-09-07 9 views
9

Mam 2D tablicę tak:?Jak szukać w tablicy 2D przez LINQ [version2]

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

wyszukiwać ClassName w 1ND kolumny dla rachunku i powrócić ColorName w kolumny tak:

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; 
    } 
} 

chcę używać LINQ zamiast dla oświadczenia uzyskać kolorprzez className. jak przekonwertować powyższy zestaw instrukcji do LINQ.

+2

Twoja tablica 2D wygląda tak, jakby to był słownik? –

+0

Tablica 2D jest w rzeczywistości materiałem 'c', w języku C# powinniśmy używać innych struktur/klas kolekcji. –

Odpowiedz

11

Możesz użyć metody do wygenerowania sekwencji liczb całkowitych, a następnie użyj Linq, aby zapytać o to.

Coś jak to będzie działać:

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

Albo w składni zapytania:

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

A może przekształcić tablicę do Dictionary<string, string> pierwszy:

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

a następnie można zapytaj o wiele łatwiej:

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

Najpierw generowanie słownika, a następnie wysyłanie zapytań będzie znacznie bardziej efektywne, jeśli będzie trzeba wykonać wiele takich zapytań.

+0

co to jest "??" –

+0

@SamieyMehdi To jest [operator koalescencji zerowej] (http://msdn.microsoft.com/en-us/library/ms173224.aspx). Zasadniczo oznacza to "jeśli wartość po lewej stronie ma wartość zerową, zamiast tego użyj wartości po prawej". Zauważ, że działa to tylko dla typów referencyjnych lub zerowych. Jeśli twoja aktualna tablica to 'int [,]', będziesz musiał rzucić wynik na '(int?)' W klauzuli select, aby to zadziałało. –

3

Tutaj jesteś:

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(); 

Ale szczerze mówiąc, ja nigdy nie używać LINQ to zrobić. Jest mniej wydajny, mniej czytelny i gorzej utrzymany. Powinieneś rozważyć użycie istniejących pętli for lub zmienić strukturę danych na: List<CustomClass> lub Dictionary<string, string> zamiast string[,].

+0

nie działa, błąd: Sekwencja nie zawiera elementów –

+1

Otrzymasz ten błąd, gdy nie ma pasujących elementów. Przetestowałem to z twoimi przykładowymi danymi wejściowymi i zwróciłem '' Red' '. – MarcinJuraszek