10
votes

Split String en 512 Chunks de Char

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.

Y a-t-il une bonne façon, comme une boucle ou donc de faire cela?


7 commentaires

Êtes-vous sûr d'avoir besoin de 512 CHART CHUNKS? Parce que c'est différent de 512 octets qui est une contrainte plus courante.


@Henk: D'autre part, la division texte en morceaux basés sur octets 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 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


8 Réponses :



1
votes
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

1 commentaires

Omet de fournir le dernier morceau dans ce cas.



-1
votes

quelque chose comme? XXX


0 commentaires

1
votes

Je oserai fournir une version plus linqifiée de la solution de Jon, sur la base du fait que la chaîne fichier implémente ienumerable : xxx


5 commentaires

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 ce qui en fait beaucoup plus de bouffée ...


@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 méthodes d'extension dans l'assistant déroulant.


ahh les gars qui l'explique, merci ... et j'ai été dérouté par cela pendant quelques minutes hahaa



3
votes

Utilisation de la mise en œuvre de Jon et le mot clé de rendement . XXX


2 commentaires

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é



3
votes

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})");


2 commentaires

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!



1
votes

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): xxx

ou en utilisant a ( édité : 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 ): xxx

qui pourrait également être utilisé avec la boucle DO / TIME;)


0 commentaires

0
votes

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 ();
  }
}


0 commentaires