Peut-être une question fondamentale mais disons que j'ai une chaîne de 2000 caractères de 2000, j'ai besoin de diviser cette chaîne en morceaux de 512 morceaux de caractère chacun. P>
Y a-t-il une bonne façon, comme une boucle ou donc de faire cela? P>
8 Réponses :
quelque chose comme ceci: ou juste pour itérer sur: p> Notez que cela se divise en morceaux de code UTF-16 Unités, qui n'est pas tout à fait la même chose que de fractionnement dans des morceaux de points de code Unicode, ce qui peut ne pas être la même chose que la fractionnement en morceaux de glyphes. p> p>
Cet algorithme (et sa Compatibilité i> avec Unicode) a été discuté également sur l'examen du code: diviser une chaîne dans morceaux de la même longueur .
@ADRIANOREPETTI: Merci - J'ai également ajouté une petite note sur la réponse.
static IEnumerable<string> Split(string str, int chunkSize)
{
int len = str.Length;
return Enumerable.Range(0, len / chunkSize).Select(i => str.Substring(i * chunkSize, chunkSize));
}
source: Splitting a string into chunks of a certain size
Omet de fournir le dernier morceau dans ce cas.
quelque chose comme?
Je oserai fournir une version plus linqifiée de la solution de Jon, sur la base du fait que la chaîne code> fichier code> implémente ienumerable
J'ai considéré que, d'autant plus que Morelinq fournit une belle méthode de partition pour ce genre de chose. Cependant, l'efficacité de ce serait absolument horrible :(
BTW String, n'a pas de méthode d'extension pour "Skip" que vous devriez faire en premier.
Et je sais que cela implémente iénumerable
@Stan: L'équipe C # vs codé dur Les aides déposées à chaîne: il s'agit d'un cas exceptionnel où vous ne voyez pas les méthodes d'extension fournies par le cadre. Ils ont trouvé cela plus clair. L'équipe VB a décidé contrairement: vous voyez ici le iEnumerable
ahh les gars qui l'explique, merci ... et j'ai été dérouté par cela pendant quelques minutes hahaa
Utilisation de la mise en œuvre de Jon et le mot clé fort> de rendement fort>.
Utilisation intéressante de VS My This ... J'essaie de décider qui est plus facile à lire. Vous n'avez pas besoin de la pause de rendement à la fin, BTW.
J'ai pris la liberté pour réparer la pause de rendement redondante comme @jon mentionné
Cependant, bien que cette question ait une réponse acceptée, voici une version courte à l'aide d'expressions régulières. Les puristes peuvent ne pas l'aimer (naturellement) mais lorsque vous avez besoin d'une solution rapide et que vous êtes utile avec des regexes, cela peut être. La performance est plutôt bonne, surprenante:
string [] split = Regex.Split(yourString, @"(?<=\G.{512})");
Utile pour inspecter de longues chaînes dans une fenêtre immédiate.
Pourquoi pas? C'est court, assez rapide et clair (si vous savez des regextes, je devais personnellement la lire et le tester 3 fois). Belle version!
La plupart de la réponse peuvent avoir la même faille. Étant donné un texte vide, ils ne produiront rien. Nous (i) nous attendons au moins pour récupérer cette chaîne vide (même comportement qu'une scission sur un caractère non dans la chaîne, qui donnera un élément: cette chaîne donnée)
Nous devons donc faire boucle au moins une fois tous les temps. (Basé sur le code de Jon): p> ou en utilisant a ( édité fort>: Après avoir joué un peu plus avec cela, j'ai trouvé une meilleure façon de gérer le boîtier chunksize supérieur au texte em>): p> qui pourrait également être utilisé avec la boucle DO / TIME;) P> p>
Méthode d'extension générique:
using System;
using System.Collections.Generic;
using System.Linq;
public static class IEnumerableExtensions
{
public static IEnumerable<IEnumerable<T>> SplitToChunks<T> (this IEnumerable<T> coll, int chunkSize)
{
int skipCount = 0;
while (coll.Skip (skipCount).Take (chunkSize) is IEnumerable<T> part && part.Any ())
{
skipCount += chunkSize;
yield return part;
}
}
}
class Program
{
static void Main (string[] args)
{
var col = Enumerable.Range(1,1<<10);
var chunks = col.SplitToChunks(8);
foreach (var c in chunks.Take (200))
{
Console.WriteLine (string.Join (" ", c.Select (n => n.ToString ("X4"))));
}
Console.WriteLine ();
Console.WriteLine ();
"Split this text into parts that are fifteen characters in length, surrounding each part with single quotes and output each into the console on seperate lines."
.SplitToChunks (15)
.Select(p => $"'{string.Concat(p)}'")
.ToList ()
.ForEach (p => Console.WriteLine (p));
Console.ReadLine ();
}
}
Êtes-vous sûr d'avoir besoin de 512 CHART B> CHUNKS? Parce que c'est différent de 512 octets b> qui est une contrainte plus courante.
@Henk: D'autre part, la division texte i> en morceaux basés sur octets i> serait assez étrange - les résultats dépendraient du codage.
Jon, oui, un problème courant lors de la ré-assemblage du texte. Mais certains canaux d'E / S fonctionnent dans des blocs de 512 octets.
@Jon et @henk: la chaîne
code> in c # est définie pour contenir des caractères UTF-16 en interne, le codage n'est pas pertinent en mémoire, une fois que vous l'avez écrite sur le disque (ou ailleurs), le codage devient pertinent et influence la taille d'octet stocké.Abel, je sais et Jon aussi. Je demandais à Meep de confirmer à quel niveau la condition s'applique à la condition. 512 est un nombre beaucoup plus rondeur pour des octets que pour les caractères.
Ah, désolé, bien sûr (je me suis réagi sur "dépendrait de l'encodage", je vois maintenant ce que vous vouliez dire).
Dupliqué possible de division d'une ficelle dans des morceaux d'une certaine taille a>