Utilisation de la syntaxe de la méthode d'extension LINQ sur un MatchCollection


92

J'ai le code suivant:

MatchCollection matches = myRegEx.Matches(content);

bool result = (from Match m in matches
               where m.Groups["name"].Value.Length > 128
               select m).Any();

Existe-t-il un moyen de le faire en utilisant la syntaxe de la méthode d'extension LINQ?

Quelque chose comme ça:

bool result = matches.Any(x => ... );

Réponses:


192
using System.Linq;

matches.Cast<Match>().Any(x => x.Groups["name"].Value.Length > 128)

Il vous suffit de le convertir de un IEnumerableen un IEnumerable<Match>(IEnumerable <T>) pour accéder à l'extension LINQ fournie sur IEnumerable <T>.


Qui vote toutes les réponses ici? Cette réponse me plaît, cognrats.
— Kevin Kalitowski le

+1 J'essaie de comprendre pourquoi ce vote a été rejeté. Je ne le vois pas.
— jason le

Je suis vraiment confus quant à la façon dont cela a été voté car il est correct
— msarchet

1
Cela fonctionne, assurez-vous simplement que vous êtes using System.Linqsinon, cela donnera une erreur de syntaxe
— Ash Berlin-Taylor

1
Merci, à tous ceux qui sont confus, ce Castn'est pas nécessaire depuis C # 8.0, mais le code ne sera pas compilé dans les versions linguistiques antérieures s'il n'est pas fourni.
— rvnlord

46

Lorsque vous spécifiez un type de variable de plage explicite , le compilateur insère un appel à Cast<T>. Donc ça:

bool result = (from Match m in matches
               where m.Groups["name"].Value.Length > 128
               select m).Any();

équivaut exactement à:

bool result = matches.Cast<Match>()
                     .Where(m => m.Groups["name"].Value.Length > 128)
                     .Any();

qui peut aussi s'écrire:

bool result = matches.Cast<Match>()
                     .Any(m => m.Groups["name"].Value.Length > 128);

Dans ce cas, l' Castappel est requis car MatchCollectionimplémente uniquement ICollectionet IEnumerable, pas IEnumerable<T>. Presque toutes les méthodes d'extension LINQ to Objects sont ciblées IEnumerable<T>, à l'exception notable de Castet OfType, qui sont tous deux utilisés pour convertir une collection typée "faiblement" (telle que MatchCollection) en un générique IEnumerable<T>- qui permet ensuite d'autres opérations LINQ.



8

Essaye ça:

var matches = myRegEx.Matches(content).Cast<Match>();

Pour référence, veuillez consulter Enumerable.Cast:

Convertit les éléments d'un IEnumerabledans le type spécifié.

Fondamentalement, c'est une façon de transformer un IEnumerablefichier IEnumerable<T>.


+1 J'essaie de comprendre pourquoi ce vote a été rejeté. Je ne le vois pas.
— jason le

@Jason: Très probablement, quelqu'un essayait de renforcer sa réponse.
— Andrew Hare

3

Je pense que ce serait quelque chose comme ça:

bool result = matches.Cast<Match>().Any(m => m.Groups["name"].Value.Length > 128);

1
Non. Le fait est que MatchCollectionseuls les outils IEnumerable. Il n'est pas fortement typé.
— jason le

2

Vous pouvez essayer quelque chose comme ceci:

List<Match> matchList = matches.Cast<Match>().Where(m => m.Groups["name"].Value.Length > 128).ToList();

-1

ÉDITER:

 public static IEnumerable<T> AsEnumerable<T>(this IEnumerable enumerable)
 {
      foreach(object item in enumerable)
          yield return (T)item;
 }

Ensuite, vous devriez pouvoir appeler cette méthode d'extension pour la transformer en un IEnumerable:

 matches.AsEnumerable<Match>().Any(x => x.Groups["name"].Value.Length > 128);

C'est mieux que le mien, je ne me souvenais pas qu'Any prenait un prédicat.
— pstrjds

Non. Le fait est que MatchCollectionseuls les outils IEnumerable. Il n'est pas fortement typé.
— jason le

@Jason sauf qu'il peut être converti en un IEnumberable <T> via IEnumberable.Cast <T>
— msarchet

@msarchet: Oui, je sais, c'est pourquoi j'ai voté pour votre réponse. Cette réponse, avant la modification, n'aurait même pas été compilée.
— jason le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.