Je l'ai rencontré plusieurs fois dans le passé et j'ai finalement décidé de savoir pourquoi.
StringSplitOptions.RemoveEmptyEntries
suggère qu'il supprime les entrées vides.
Alors, pourquoi ce test échoue-t-il?
var tags = "One, Two, , Three, Foo Bar, , Day , ";
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim());
tagsSplit.ShouldEqual(new string[] {
"One",
"Two",
"Three",
"Foo Bar",
"Day"
});
Le résultat:
Values differ at index [2]
Expected string length 5 but was 0. Strings differ at index 0.
Expected: "Three"
But was: <string.Empty>
Donc, cela échoue car au lieu de "Three"
, nous avons une chaîne vide - exactement ce que StringSplitOptions.RemoveEmptyEntries
devrait empêcher.
Probablement parce que vous modifiez la chaîne après la scission. Vous coupez les valeurs après les avoir fractionnées, RemoveEmptyEntries
ne considère pas la chaîne " "
vide.
Vous obtiendrez ce que vous voulez en créant vos propres éléments vides de bande:
var tagsSplit = tags.Split(',').
Select(tag => tag.Trim()).
Where( tag => !string.IsNullOrEmpty(tag));
Les délimiteurs adjacents génèrent un élément de tableau contenant un empty chaîne (""). Les valeurs de l'énumération StringSplitOptions spécifient si un élément de tableau contenant une chaîne vide est inclus dans le tableau retourné.
" "
par définition n'est pas vide (il s'agit en fait de espaces), de sorte qu'il n'est pas supprimé du tableau résultant.
Si vous utilisez .net framework 4, vous pouvez résoudre ce problème en utilisant string.IsNullOrWhitespace, méthode
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(s => s.Trim());
RemoveEmptyEntries ne signifie pas d'espace.
Votre chaîne d'entrée contient de nombreux "espaces". Vous devriez remarquer que "l'espace" n'est pas vide. Dans l’ordinateur, l’espace est un code spécial ASCII. alors le code:
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim());
veux dire:
C'est pour ça que vous l'avez.
Essayer
var tagsSplit = tags.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
Cela crache par virgule et par espace et élimine les chaînes vides.
J'ai également cherché un moyen propre d'exclure les espaces blancs pendant un fractionnement, mais comme toutes les options semblaient être une sorte de solution de contournement, j'ai choisi de les exclure lorsque vous parcourez le tableau.
string[] tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tag in tagsSplit.Where(t => !string.IsNullOrWhiteSpace(t))) { }
Je pense que cela a l'air plus propre et - en prime - que .Split(...).ToArray()
peut être omis .. Bien sûr, c'est une option uniquement lorsque vous pouvez effectuer une boucle juste après la scission et ne pas avoir à stocker des entrées pour une utilisation ultérieure.
var tagsSplit = tags.Split(',')
.Where(str => str != String.IsNullOrWhiteSpace(str))
.Select(s => s.Trim());
Comme il s'agit d'un besoin très courant, je suis allé de l'avant et j'ai intégré la réponse la plus populaire à une méthode d'extension de chaîne:
public static IEnumerable<string> Split_RemoveWhiteTokens(this string s, params char[] separator)
{
return s.Split(separator).
Select(tag => tag.Trim()).
Where(tag => !string.IsNullOrEmpty(tag));
}
Pour diviser sur ',' comme les autres exemples, utilisez comme ceci:
var result = yourString.Split_RemoveWhiteTokens(',')
Notez que le type de retour est IEnumerable, vous pouvez donc effectuer des requêtes LINQ supplémentaires directement sur le résultat du retour. Appelez .ToList () si vous souhaitez convertir le résultat en liste.