Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to search in 2D array by LINQ ?[version2]

I have an 2D array like this:

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

i search ClassName in 1nd column by for statement and return ColorName in 2nd column like this:

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

i want use LINQ instead of for statement to get the color by className. how to convert above for statement to LINQ.

like image 421
Samiey Mehdi Avatar asked Sep 07 '13 13:09

Samiey Mehdi


Video Answer


2 Answers

You can do use the Enumerable.Range method to generate a sequence of integers, and then use Linq to query over that.

Something like this would work:

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

Or in query syntax:

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

Or perhaps convert the array to a Dictionary<string, string> first:

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

And then you can query it much more easily:

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

Generating the dictionary first and then querying it will be far more efficient if you have to do a lot of queries like this.

like image 132
p.s.w.g Avatar answered Sep 20 '22 20:09

p.s.w.g


Here you are:

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

But to be honest, I would never use LINQ to do that. It's less efficient, less readable and worse to maintain. You should consider using your existing for loops or change your data structure, to be List<CustomClass> or Dictionary<string, string> instead of string[,].

like image 25
MarcinJuraszek Avatar answered Sep 18 '22 20:09

MarcinJuraszek