how would I use the following LINQ query correctly? I want to create a one dimensional array that contains only values that are greater than 5. I can't understand why it can't iterate over this multidimensional array, but if I'll use "foreach" it'd actually iterate.
// Create an multidimensional array, then just put numbers into it and print the array.
int[,] myArr = new int[5,6];
int rows = myArr.GetLength(0);
int cols = myArr.GetLength(1);
for (int i = 0; i < rows; i++)
{
for (int k = 0; k < cols; k++)
{
myArr[i,k] = i + k;
Console.Write(myArr[i,k]);
}
Console.WriteLine("");
}
var highList = from val in myArr where (val > 5) select val;
The error is: Error 1 Could not find an implementation of the query pattern for source type 'int[,]'. 'Where' not found. Are you missing a reference or a using directive for 'System.Linq'?
I thought this might fix the problem:
public static IEnumerator<int> GetEnumerator(int[,] arr)
{
foreach(int i in arr)
{
yield return i;
}
}
But I guess it doesn't really implement the iterator. I'm sorry if I'm talking weird things here, I'm kind of new to those things... Thank you.
The problem is that multi-dimensional (rectangular) arrays implement IEnumerable
, but not IEnumerable<T>
. Fortunately, you can use Cast
to fix that - and Cast
gets called automatically if you explicitly specify the type of the range variable:
var highList = from int val in myArr where (val > 5) select val;
Or without the unnecessary brackets:
var highList = from int val in myArr where val > 5 select val;
Or using method calls directly, given that it's a pretty trivial query expression:
var highList = myArr.Cast<int>().Where(val => val > 5);
I think this will box each element, however. You could add your own Cast
extension method to avoid that:
public static class RectangularArrayExtensions
{
public static IEnumerable<T> Cast<T>(this T[,] source)
{
foreach (T item in source)
{
yield return item;
}
}
}
See more on this question at Stackoverflow