views:

83

answers:

2

I know, this is very simple for you guys. Please consider the following code:

string[] str = { "dataReader", "dataTable", "gridView", "textBox", "bool" };

            var s = from n in str
                    where n.StartsWith("data")
                    select n;

            foreach (var x in s)
            {
                Console.WriteLine(x.ToString());
            }
            Console.ReadLine();

Supposedly, it will print:

dataReader
dataTable

right?

What if for example I don't know the data, and what the results of the query will be (but I'm sure it will return some results) and I just want to print the second item that will be produced by the query, what should my code be instead of using foreach?

Is there something like array-indexing here?

+7  A: 

You're looking forEnumerable.ElementAt.

var secondMatch = str.Where(item => item.StartsWith("data")) //consider null-test
                     .ElementAt(1); 

Console.WriteLine(secondMatch); //ToString() is redundant

SinceWherestreams its results, this will be efficient - enumeration of the source sequence will be discontinued after the second match (the one you're interested in) has been found.

If you find that the implicit guarantee you have that the source will contain two matches is not valid, you can use ElementAtOrDefault.

var secondMatch = str.Where(item => item.StartsWith("data"))
                     .ElementAtOrDefault(1); 

if(secondMatch == null) // because default(string) == null
{
   // There are no matches or just a single match..
}
else
{
  // Second match found..
}

You could use array-indexing here as you say, but only after you load the results into... an array. This will of course mean that the entire source sequence has to be enumerated and the matches loaded into the array, so it's a bit of a waste if you are only interested in the second match.

var secondMatch = str.Where(item => item.StartsWith("data"))
                     .ToArray()[1]; //ElementAt will will work too
Ani
+1 ElementAtOrDefault, didn't know that existed.
Vivek
thank you sir for the answer :)
yonan2236
+5  A: 

you got a few options:

s.Skip(1).First();
s.ElementAt(1);

The first is more suited for scenarios where you want X elements but after the y first elements. The second is more clear when you just need a single element on a specific location

Rune FS