Quelle est la façon la plus efficace d'écrire à l'ancienne:
StringBuilder sb = new StringBuilder();
if (strings.Count > 0)
{
foreach (string s in strings)
{
sb.Append(s + ", ");
}
sb.Remove(sb.Length - 2, 2);
}
return sb.ToString();
... dans LINQ?
c#
linq
string-concatenation
tags2k
la source
la source
Réponses:
Cette réponse montre l'utilisation de LINQ (
Aggregate
) comme demandé dans la question et n'est pas destinée à un usage quotidien. Parce que cela n'utilise pas un,StringBuilder
il aura des performances horribles pour de très longues séquences. Pour une utilisation régulière du codeString.Join
comme indiqué dans l'autre réponseUtilisez des requêtes agrégées comme celle-ci:
Cela produit:
Un agrégat est une fonction qui prend une collection de valeurs et renvoie une valeur scalaire. Les exemples de T-SQL incluent min, max et sum. VB et C # prennent en charge les agrégats. VB et C # prennent en charge les agrégats en tant que méthodes d'extension. En utilisant la notation par points, on appelle simplement une méthode sur un IEnumerable objet .
N'oubliez pas que les requêtes agrégées sont exécutées immédiatement.
Plus d'informations - MSDN: requêtes agrégées
Si vous voulez vraiment utiliser
Aggregate
use variant usingStringBuilder
propose en commentaire par CodeMonkeyKing qui serait à peu près le même code que regularString.Join
incluant de bonnes performances pour un grand nombre d'objets:la source
""
, la première valeur utilisée danscurrent
est une chaîne vide. Ainsi, pour 1 ou plusieurs éléments, vous obtiendrez toujours,
au début de la chaîne.Dans .Net 4, il y a une nouvelle surcharge pour
string.Join
cela accepteIEnumerable<string>
. Le code ressemblerait alors à:la source
Pourquoi utiliser Linq?
Cela fonctionne parfaitement et accepte tout
IEnumerable<string>
autant que je me souvienne. Pas besoin deAggregate
quoi que ce soit ici qui est beaucoup plus lent.la source
String.Join(",", s.ToArray())
dans les anciennes versions.Avez-vous examiné la méthode d'extension d'agrégat?
la source
Exemple réel de mon code:
Une requête est un objet qui a une propriété Name qui est une chaîne, et je veux les noms de toutes les requêtes de la liste sélectionnée, séparés par des virgules.
la source
Voici l'approche combinée Join / Linq sur laquelle j'ai opté après avoir examiné les autres réponses et les problèmes abordés dans une question similaire (à savoir que l'agrégation et la concaténation échouent avec 0 élément).
string Result = String.Join(",", split.Select(s => s.Name));
ou (si ce
s
n'est pas une chaîne)string Result = String.Join(",", split.Select(s => s.ToString()));
StringBuilder
) à implémenterEt bien sûr, Join s'occupe de la virgule finale embêtante qui se glisse parfois dans d'autres approches (
for
,foreach
), c'est pourquoi je cherchais une solution Linq en premier lieu.la source
.Select()
comme celle-ci fournit un endroit facile pour modifier chaque élément pendant cette opération. Par exemple, en emballant chaque élément dans un caractère comme celui-cistring Result = String.Join(",", split.Select(s => "'" + s + "'"));
Vous pouvez utiliser
StringBuilder
dansAggregate
:(Le
Select
est là juste pour montrer que vous pouvez faire plus de choses LINQ.)la source
new[] {"one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) =>{if (sb.Length > 0) sb.Append(", ");sb.Append(s);return sb;}).ToString();
if (length > 0)
le linq et en le retirant.new[] {"", "one", "two", "three"}.Aggregate(new StringBuilder(), (sb, s) => (String.IsNullOrEmpty(sb.ToString())) ? sb.Append(s) : sb.Append(", ").Append(s)).ToString();
données de performances rapides pour le cas StringBuilder vs Select & Aggregate sur 3000 éléments:
Test unitaire - Durée (secondes)
LINQ_StringBuilder - 0,0036644
LINQ_Select.Aggregate - 1,8012535
la source
J'utilise toujours la méthode d'extension:
la source
string.Join
dans .net 4 peut déjà prendre unIEnumerable<T>
pour tout arbitraireT
.Par « voie LINQ super cool », vous pourriez parler de la façon dont LINQ rend la programmation fonctionnelle beaucoup plus acceptable avec l'utilisation de méthodes d'extension. Je veux dire, le sucre syntaxique qui permet d'enchaîner les fonctions de manière visuellement linéaire (l'une après l'autre) au lieu de s'emboîter (l'une dans l'autre). Par exemple:
peut être écrit comme ceci:
Vous pouvez voir comment le deuxième exemple est plus facile à lire. Vous pouvez également voir comment plus de fonctions peuvent être ajoutées avec moins de problèmes d'indentation ou les parens de fermeture Lispy apparaissant à la fin de l'expression.
Beaucoup d'autres réponses indiquent que
String.Join
c'est la voie à suivre, car c'est la plus rapide ou la plus simple à lire. Mais si vous prenez mon interprétation de la ` ` façon LINQ super cool '', la réponse est d'utiliserString.Join
mais de l'envelopper dans une méthode d'extension de style LINQ qui vous permettra d'enchaîner vos fonctions d'une manière visuellement agréable. Donc, si vous voulez écrire, ilsa.Concatenate(", ")
vous suffit de créer quelque chose comme ceci:Cela fournira un code aussi performant que l'appel direct (au moins en termes de complexité de l'algorithme) et dans certains cas, rendra le code plus lisible (selon le contexte), surtout si un autre code du bloc utilise le style de fonction chaîné .
la source
Il existe différentes réponses alternatives à cette question précédente - qui visait certes un tableau entier comme source, mais a reçu des réponses généralisées.
la source
Ici, il utilise LINQ pur comme une seule expression:
Et c'est sacrément rapide!
la source
Je vais tricher un peu et lancer une nouvelle réponse à cela qui semble résumer le meilleur de tout ici au lieu de la coller dans un commentaire.
Vous pouvez donc une ligne:
Modifier: vous souhaiterez d'abord vérifier un énumérable vide ou ajouter un
.Replace("\a",string.Empty);
à la fin de l'expression. Je suppose que j'aurais pu essayer d'être un peu trop intelligent.La réponse de @ a.friend pourrait être légèrement plus performante, je ne sais pas ce que remplace Replace sous le capot par rapport à Remove. La seule autre mise en garde si une raison pour laquelle vous vouliez concaténer des chaînes qui se terminaient par \ a, vous perdriez vos séparateurs ... Je trouve cela peu probable. Si tel est le cas, vous avez le choix entre d' autres personnages fantaisistes .
la source
Vous pouvez combiner LINQ et
string.join()
assez efficacement. Ici, je supprime un élément d'une chaîne. Il existe de meilleures façons de le faire aussi, mais voici:la source
Beaucoup de choix ici. Vous pouvez utiliser LINQ et un StringBuilder pour obtenir les performances aussi comme ceci:
la source
builder.Length > 0
dans le ForEach et en supprimant la première virgule après le ForEachJ'ai fait ce qui suit rapidement et sale lors de l'analyse d'un fichier journal IIS à l'aide de linq, cela a fonctionné assez bien @ 1 million de lignes (15 secondes), bien que j'ai obtenu une erreur de mémoire insuffisante lors de l'essai de 2 millions de lignes.
La vraie raison pour laquelle j'ai utilisé linq était pour un Distinct () dont j'avais besoin auparavant:
la source
J'ai blogué à ce sujet il y a quelque temps, ce que j'ai fait semble être exactement ce que vous recherchez:
http://ondevelopment.blogspot.com/2009/02/string-concatenation-made-easy.html
Dans le billet de blog, décrivez comment implémenter des méthodes d'extension qui fonctionnent sur IEnumerable et sont nommées Concatenate, cela vous permettra d'écrire des choses comme:
Ou des choses plus élaborées comme:
la source