I’ve been teaching myself LINQ recently and applying it to various little puzzles. However, one of the problems I have run into is that LINQ-to-objects only works on generic collections. Is there a secret trick/ best practice for converting a non-generic collection to a generic collection?
My current implementation copies the non-generic collection to an array then operates on that, but I was wondering if there was a better way?
public static int maxSequence(string str)
{
MatchCollection matches = Regex.Matches(str, "H+|T+");
Match[] matchArr = new Match[matches.Count];
matches.CopyTo(matchArr, 0);
return matchArr
.Select(match => match.Value.Length)
.OrderByDescending(len => len)
.First();
}
The simplest way is usually the
Castextension method:Note that this is deferred and streams its data, so you don’t have a full “collection” as such – but it’s a perfectly fine data source for LINQ queries.
Castis automatically called if you specify a type for the range variable in a query expression:So to convert your query completely:
or
In fact, you don’t need to call
OrderByDescendingand thenFirsthere – you just want the maximal value, which theMaxmethod gets you. Even better, it lets you specify a projection from a source element type to the value you’re trying to find, so you can do without theSelecttoo:If you have a collection which has some elements of the right type but some which may not be, you can use
OfTypeinstead.Castthrows an exception when it encounters an item of the “wrong” type;OfTypejust skips over it.