Générique LINQ fonction - SelectMany avec la sélection Func comme paramètre
J'ai une classe avec de nombreux tableaux de chaîne. J'aimerais avoir une fonction générique qui peut me faire une unique List<string>
pour une propriété donnée. Exemple:
public class Zoo
{
string Name { get; set;}
string[] Animals { get; set;}
string[] Zookeepers { get; set;}
string[] Vendors { get; set;}
}
J'aimerais avoir une fonction générique qui va me faire un distinct List<string>
des Animaux dans la Liste? Je veux que ce soit générique, donc je peux également obtenir une liste distincte de gardiens de zoo et les Fournisseurs.
J'ai essayé ceci, mais il ne compile pas:
public static List<string> GetExtendedList(Func<Zoo, string[]> filter)
{
var Zoos = QueryZoos(HttpContext.Current);
return Zoos.Where(z => z.Type == "Active")
.SelectMany(filter)
.Distinct()
.OrderBy(s => s);
}
Note: ceci est lié à deux questions que j'ai demandé avant, mais je vais avoir de la difficulté à la fusion de l'information. Je l'avais déjà demandé comment requête à l'aide de SelectMany (DONC 1229897) et séparément demandé comment écrire une fonction générique qui obtient une liste à l'aide de Sélectionner plutôt que SelectMany (DONC 1278989).
OriginalL'auteur Jon Galloway | 2009-09-03
Vous devez vous connecter pour publier un commentaire.
cliquez sur
Supposons que vous ayez une liste de zoo:
Alors, si vous vouliez distinctes les animaux de tous les zoos, vous appliquez SelectMany de cette façon:
Et Si vous avez l'habitude fait de cette tâche et je voulais une fonction d'envelopper ces trois appels, vous pouvez écrire une telle fonction de cette manière:
Qui serait alors appelé:
Et pour l'exemple de code qui ne compile pas (pour lequel vous avez reçu aucun message d'erreur), j'en déduis que vous devez ajouter un ToList():
L'autre problème (pourquoi l'argument de type ne peut pas être déduite), c'est que
string[]
ne pas mettre en œuvreIEnumerable<string>
. Modifier ce paramètre de type deIEnumerable<string>
au lieu destring[]
Merci, cela a très bien fonctionné. Je vais accepter et va chercher à le convertir à une non-méthode d'extension juste pour m'assurer de bien le comprendre. Le principal problème que j'ai eu, semble être, en déclarant la touche Func param correctement.
En fait,
string[]
ne mettre en œuvreIEnumerable<string>
. Le vrai problème est queFunc<Zoo, string[]>
est un type délégué qui est différent deFunc<Zoo, IEnumerable<string>>
; et les différents types délégués ne sont pas directement compatibles.OriginalL'auteur Amy B
La meilleure façon serait de créer un
HashSet<String>
pour chaqueString[]
- ce serait de filtrer tous les doublons.Depuis
HashSet<T>
a un constructeur qui accepte unIEnumerable<T>
, il vous suffit d'instancier unHashSet<T>
en passant chacun de vos tableaux dans le constructeur. Le résultantHashSet<T>
serait la liste distincte deStrings
. Alors que ce n'est pas unList<String>
comme vous l'avez demandé,HashSet<T>
ne mettre en œuvreICollection<T>
donc de nombreuses méthodes vous devrez peut-être disponibles.Hmm.. je vois ce que tu veux dire. Est refactoring la
Zoo
type une option?Il pourrait être, mais j'aimerais vraiment apprendre le LINQ solution plutôt que de simplement en reformulant le problème, chaque fois que j'ai frappé. Apprécier l'entrée, tout de même!
OriginalL'auteur Andrew Hare
Peut-être que je suis absent de ce que tu veux dire, mais tout simplement...
à faire ce que vous demandez, je suppose que vous voulez dire quelque chose d'autre?
Edit:
Si vous avez une liste des Zoos, mais veulent les différents animaux, puis sélectionnez un grand nombre de est la chose correcte à utiliser, de l'OMI, il est plus facile à l'aide de linq syntaxe déclarative...
Désolé, ma question n'était pas clairement indiqué. Je suis à la recherche d'une solution générique. J'ai mis à jour la question de la déclaration.
Ah je vois ce que tu veux dire maintenant, après la Modifier. Je pense que Andrew a la réponse correcte.
Oups, je voulais dire David B a la réponse correcte.
OriginalL'auteur Tim Jarvis