What is the best way to convert a non-shared collection to a shared collection?

I recently taught LINQ and applied it to various small puzzles. However, one of the problems I ran into is that LINQ-to-objects only works with shared collections. Is there a secret trick / best practice for converting a non-shared collection to a common collection?

My current implementation copies a non-shared collection to an array and then works on it, but I was wondering if there is 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(); } 
+7
generics c # linq-to-objects
source share
3 answers

The easiest way is the Cast method:

 IEnumerable<Match> strongMatches = matches.Cast<Match>(); 

Note that this is delayed and passes on its data, so you do not have a complete β€œcollection” as such, but it is a great data source for LINQ queries.

Cast automatically called if you specify the type of the range variable in the query expression:

So, to completely convert your request:

 public static int MaxSequence(string str) { return (from Match match in Regex.Matches(str, "H+|T+") select match.Value.Length into matchLength orderby matchLength descending select matchLength).First(); } 

or

 public static int MaxSequence(string str) { MatchCollection matches = Regex.Matches(str, "H+|T+"); return matches.Cast<Match>() .Select(match => match.Value.Length) .OrderByDescending(len => len) .First(); } 

In fact, you do not need to call OrderByDescending , and then First here - you just want to get the maximum value that the Max method will receive. Even better, it allows you to specify the projection from the type of the source element to the value you are trying to find, so you can do without Select :

 public static int MaxSequence(string str) { MatchCollection matches = Regex.Matches(str, "H+|T+"); return matches.Cast<Match>() .Max(match => match.Value.Length); } 

If you have a collection that has some elements of the desired type, but some of which may be missing, you can use OfType . Cast throws an exception when it encounters an element of the "wrong" type; OfType just skips it.

+10
source share

You can use Cast or OfType on IEnumerable to convert. Cast will cause illegal listing if the element cannot be passed to the specified type, and OfType will skip any elements that cannot be converted.

+1
source share
 matches.Cast<Match>(); 
0
source share

All Articles