LINQ Aggregate Les types complexes dans une chaîne
-
19-09-2019 - |
Question
Je l'ai vu l'exemple simple de la fonction .net globale de travail comme ceci:
string[] words = { "one", "two", "three" };
var res = words.Aggregate((current, next) => current + ", " + next);
Console.WriteLine(res);
Comment la fonction « globale » pourrait être utilisé si vous souhaitez regrouper les types plus complexes? Par exemple: une classe avec 2 propriétés telles que « clé » et « valeur » et vous voulez que la sortie comme ceci:
"MyAge: 33, MyHeight: 1.75, MyWeight:90"
La solution
Vous avez deux options:
-
Projet à un
string
et total:var values = new[] { new { Key = "MyAge", Value = 33.0 }, new { Key = "MyHeight", Value = 1.75 }, new { Key = "MyWeight", Value = 90.0 } }; var res1 = values.Select(x => string.Format("{0}:{1}", x.Key, x.Value)) .Aggregate((current, next) => current + ", " + next); Console.WriteLine(res1);
Ceci a l'avantage d'utiliser le premier élément de
string
que la graine (pas préfixé « »), mais consomme plus de mémoire pour les chaînes créées dans le processus. -
Utiliser une surcharge globale qui accepte une graine, peut-être un
StringBuilder
:var res2 = values.Aggregate(new StringBuilder(), (current, next) => current.AppendFormat(", {0}:{1}", next.Key, next.Value), sb => sb.Length > 2 ? sb.Remove(0, 2).ToString() : ""); Console.WriteLine(res2);
Le second délégué convertit notre
StringBuilder
enstring,
utilisant le conditionnel à couper le départ "".
Autres conseils
agrégat a 3 surcharges, de sorte que vous pouvez utiliser celui qui a différents types d'accumuler les éléments que vous énumérez.
Vous devrez passer une valeur de départ (votre classe personnalisée), et une méthode pour ajouter fusionner la graine avec une valeur. Exemple:
MyObj[] vals = new [] { new MyObj(1,100), new MyObj(2,200), ... };
MySum result = vals.Aggregate<MyObj, MySum>(new MySum(),
(sum, val) =>
{
sum.Sum1 += val.V1;
sum.Sum2 += val.V2;
return sum;
}
La fonction globale accepte un paramètre de délégué. Vous définissez le comportement que vous voulez en changeant le délégué.
var res = data.Aggregate((current, next) => current + ", " + next.Key + ": " + next.Value);
Ou utilisez string.join ():
var values = new[] {
new { Key = "MyAge", Value = 33.0 },
new { Key = "MyHeight", Value = 1.75 },
new { Key = "MyWeight", Value = 90.0 }
};
var res = string.Join(", ", values.Select(item => $"{item.Key}: {item.Value}"));
Console.WriteLine(res);