Using Linq with 2D Array, Select Not Found

Using Linq with 2D array, Select not found

In order to use your multidimensional array with LINQ, you simply need to convert it to IEnumerable<T>. It's simple enough, here are two example options for querying

int[,] array = { { 1, 2 }, { 3, 4 } };

var query = from int item in array
where item % 2 == 0
select item;

var query2 = from item in array.Cast<int>()
where item % 2 == 0
select item;

Each syntax will convert the 2D array into an IEnumerable<T> (because you say int item in one from clause or array.Cast<int>() in the other). You can then filter, select, or perform whatever projection you wish using LINQ methods.

C# LINQ query on multidimensional array

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

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

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.

LINQ .Any() iterator for 2D Array - [,]

Here's a way you can flatten the list to check

bool anyZeroes = array.Cast<int>().Any(value => value == 0);// false
bool anyNines = array.Cast<int>().Any(value => value == 9);// true

Though, if you are making multiple calls you should store it:

bool casted = array.Cast<int>();
bool anyZeroes = casted.Any(value => value == 0);// false
bool anyNines = casted.Any(value => value == 9);// true

Reference: https://stackoverflow.com/a/13822900/526704

How to use LINQ on a multidimensional array to 'unwind' the array?

How about:

Enumerable
.Range(0,numbers.GetUpperBound(0)+1)
.SelectMany(x => Enumerable.Range(0,numbers.GetUpperBound(1)+1)
.Select (y =>numbers[x,y] ));

or to neaten up.

var xLimit=Enumerable.Range(0,numbers.GetUpperBound(0)+1);
var yLimit=Enumerable.Range(0,numbers.GetUpperBound(1)+1);
var result = xLimit.SelectMany(x=> yLimit.Select(y => numbers[x,y]));

EDIT Revised Question....

var result = array.SelectMany(x => x.C);

Selecting a multi-dimensional array in LINQ

I don't think it is possible. My reasoning is that Select and most other LINQ functions require that the collections they work on implement at least IEnumerable<T> for some T:

public static IEnumerable<TResult> Select<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TResult> selector
)

A rectangular array doesn't implement IEnumerable<T> for any T so it can't be the return value of a Select function.

Random 2-D array with LINQ c#

Using linq to create a 10x10 array:

   var r = new Random();
var result = Enumerable.Range(0, 10).Select(x =>
Enumerable.Range(0, 10).Select(y => r.Next()).ToArray())
.ToArray();


Related Topics



Leave a reply



Submit