Splitting a string into chunks of a certain size

后端 未结 30 1547
时光说笑
时光说笑 2020-11-22 07:55

Suppose I had a string:

string str = \"1111222233334444\"; 

How can I break this string into chunks of some size?

e.g., breaking t

相关标签:
30条回答
  • 2020-11-22 08:09

    Six years later o_O

    Just because

        public static IEnumerable<string> Split(this string str, int chunkSize, bool remainingInFront)
        {
            var count = (int) Math.Ceiling(str.Length/(double) chunkSize);
            Func<int, int> start = index => remainingInFront ? str.Length - (count - index)*chunkSize : index*chunkSize;
            Func<int, int> end = index => Math.Min(str.Length - Math.Max(start(index), 0), Math.Min(start(index) + chunkSize - Math.Max(start(index), 0), chunkSize));
            return Enumerable.Range(0, count).Select(i => str.Substring(Math.Max(start(i), 0),end(i)));
        }
    

    or

        private static Func<bool, int, int, int, int, int> start = (remainingInFront, length, count, index, size) =>
            remainingInFront ? length - (count - index) * size : index * size;
    
        private static Func<bool, int, int, int, int, int, int> end = (remainingInFront, length, count, index, size, start) =>
            Math.Min(length - Math.Max(start, 0), Math.Min(start + size - Math.Max(start, 0), size));
    
        public static IEnumerable<string> Split(this string str, int chunkSize, bool remainingInFront)
        {
            var count = (int)Math.Ceiling(str.Length / (double)chunkSize);
            return Enumerable.Range(0, count).Select(i => str.Substring(
                Math.Max(start(remainingInFront, str.Length, count, i, chunkSize), 0),
                end(remainingInFront, str.Length, count, i, chunkSize, start(remainingInFront, str.Length, count, i, chunkSize))
            ));
        }
    

    AFAIK all edge cases are handled.

    Console.WriteLine(string.Join(" ", "abc".Split(2, false))); // ab c
    Console.WriteLine(string.Join(" ", "abc".Split(2, true))); // a bc
    Console.WriteLine(string.Join(" ", "a".Split(2, true))); // a
    Console.WriteLine(string.Join(" ", "a".Split(2, false))); // a
    
    0 讨论(0)
  • 2020-11-22 08:10

    This should be much faster and more efficient than using LINQ or other approaches used here.

    public static IEnumerable<string> Splice(this string s, int spliceLength)
    {
        if (s == null)
            throw new ArgumentNullException("s");
        if (spliceLength < 1)
            throw new ArgumentOutOfRangeException("spliceLength");
    
        if (s.Length == 0)
            yield break;
        var start = 0;
        for (var end = spliceLength; end < s.Length; end += spliceLength)
        {
            yield return s.Substring(start, spliceLength);
            start = end;
        }
        yield return s.Substring(start);
    }
    
    0 讨论(0)
  • 2020-11-22 08:10
    public static IEnumerable<IEnumerable<T>> SplitEvery<T>(this IEnumerable<T> values, int n)
    {
        var ls = values.Take(n);
        var rs = values.Skip(n);
        return ls.Any() ?
            Cons(ls, SplitEvery(rs, n)) : 
            Enumerable.Empty<IEnumerable<T>>();
    }
    
    public static IEnumerable<T> Cons<T>(T x, IEnumerable<T> xs)
    {
        yield return x;
        foreach (var xi in xs)
            yield return xi;
    }
    
    0 讨论(0)
  • 2020-11-22 08:12

    It's not pretty and it's not fast, but it works, it's a one-liner and it's LINQy:

    List<string> a = text.Select((c, i) => new { Char = c, Index = i }).GroupBy(o => o.Index / 4).Select(g => new String(g.Select(o => o.Char).ToArray())).ToList();
    
    0 讨论(0)
  • 2020-11-22 08:13

    In a combination of dove+Konstatin's answers...

    static IEnumerable<string> WholeChunks(string str, int chunkSize) {
        for (int i = 0; i < str.Length; i += chunkSize) 
            yield return str.Substring(i, chunkSize);
    }
    

    This will work for all strings that can be split into a whole number of chunks, and will throw an exception otherwise.

    If you want to support strings of any length you could use the following code:

    static IEnumerable<string> ChunksUpto(string str, int maxChunkSize) {
        for (int i = 0; i < str.Length; i += maxChunkSize) 
            yield return str.Substring(i, Math.Min(maxChunkSize, str.Length-i));
    }
    

    However, the the OP explicitly stated he does not need this; it's somewhat longer and harder to read, slightly slower. In the spirit of KISS and YAGNI, I'd go with the first option: it's probably the most efficient implementation possible, and it's very short, readable, and, importantly, throws an exception for nonconforming input.

    0 讨论(0)
  • 2020-11-22 08:13
    class StringHelper
    {
        static void Main(string[] args)
        {
            string str = "Hi my name is vikas bansal and my email id is bansal.vks@gmail.com";
            int offSet = 10;
    
            List<string> chunks = chunkMyStr(str, offSet);
    
            Console.Read();
        }
    
        static List<string> chunkMyStr(string str, int offSet)
        {
    
    
            List<string> resultChunks = new List<string>();
    
            for (int i = 0; i < str.Length; i += offSet)
            {
                string temp = str.Substring(i, (str.Length - i) > offSet ? offSet : (str.Length - i));
                Console.WriteLine(temp);
                resultChunks.Add(temp);
    
    
            }
    
            return resultChunks;
        }
    }
    
    0 讨论(0)
提交回复
热议问题