Split String into smaller Strings by length variable

前端 未结 12 1919
谎友^
谎友^ 2020-12-01 07:19

I\'d like to break apart a String by a certain length variable.
It needs to bounds check so as not explode when the last section of string is not as long as or longer th

相关标签:
12条回答
  • 2020-12-01 07:54
        private string[] SplitByLength(string s, int d)
        {
            List<string> stringList = new List<string>();
            if (s.Length <= d) stringList.Add(s);
            else
            {
                int x = 0;
                for (; (x + d) < s.Length; x += d)
                {
                    stringList.Add(s.Substring(x, d));
                }
                stringList.Add(s.Substring(x));
            }
            return stringList.ToArray();
        }
    
    0 讨论(0)
  • 2020-12-01 07:55

    Easy to understand version:

    string x = "AAABBBCC";
    List<string> a = new List<string>();
    for (int i = 0; i < x.Length; i += 3)
    {
        if((i + 3) < x.Length)
            a.Add(x.Substring(i, 3));
        else
            a.Add(x.Substring(i));
    }
    

    Though preferably the 3 should be a nice const.

    0 讨论(0)
  • 2020-12-01 07:55

    I had the strange scenario where I had segmented a string, then rearranged the segments (i.e. reversed) before concatenating them, and then I later needed to reverse the segmentation. Here's an update to the accepted answer by @SLaks:

        /// <summary>
        /// Split the given string into equally-sized segments (possibly with a 'remainder' if uneven division).  Optionally return the 'remainder' first.
        /// </summary>
        /// <param name="str">source string</param>
        /// <param name="maxLength">size of each segment (except the remainder, which will be less)</param>
        /// <param name="remainderFirst">if dividing <paramref name="str"/> into segments would result in a chunk smaller than <paramref name="maxLength"/> left at the end, instead take it from the beginning</param>
        /// <returns>list of segments within <paramref name="str"/></returns>
        /// <remarks>Original method at https://stackoverflow.com/questions/3008718/split-string-into-smaller-strings-by-length-variable </remarks>
        private static IEnumerable<string> ToSegments(string str, int maxLength, bool remainderFirst = false) {
            // note: `maxLength == 0` would not only not make sense, but would result in an infinite loop
            if(maxLength < 1) throw new ArgumentOutOfRangeException("maxLength", maxLength, "Should be greater than 0");
            // correct for the infinite loop caused by a nonsensical request of `remainderFirst == true` and no remainder (`maxLength==1` or even division)
            if( remainderFirst && str.Length % maxLength == 0 ) remainderFirst = false;
    
            var index = 0;
            // note that we want to stop BEFORE we reach the end
            // because if it's exact we'll end up with an
            // empty segment
            while (index + maxLength < str.Length)
            {
                // do we want the 'final chunk' first or at the end?
                if( remainderFirst && index == 0 ) {
                    // figure out remainder size
                    var remainder = str.Length % maxLength;
                    yield return str.Substring(index, remainder);
    
                    index += remainder;
                }
                // normal stepthrough
                else {
                    yield return str.Substring(index, maxLength);
                    index += maxLength;
                }
            }
    
            yield return str.Substring(index);
        }//---  fn  ToSegments
    

    (I also corrected a bug in the original while version resulting in empty segment if maxLength==1)

    0 讨论(0)
  • 2020-12-01 07:56

    My solution:

    public static string[] SplitToChunks(this string source, int maxLength)
    {
        return source
            .Where((x, i) => i % maxLength == 0)
            .Select(
                (x, i) => new string(source
                    .Skip(i * maxLength)
                    .Take(maxLength)
                    .ToArray()))
            .ToArray();
    }
    

    I actually rather use List<string> instead of string[].

    0 讨论(0)
  • 2020-12-01 07:59

    Using Batch from MoreLinq, on .Net 4.0:

    public static IEnumerable<string> SplitByLength(this string str, int length)
    {
        return str.Batch(length, String.Concat);
    }
    

    On 3.5 Concat need an array, so we can use Concat with ToArray or, new String:

    public static IEnumerable<string> SplitByLength(this string str, int length)
    {
        return str.Batch(length, chars => new String(chars.ToArray()));
    }
    

    It may be a bit unintuitive to look at a string as a collection of characters, so string manipulation might be proffered.

    0 讨论(0)
  • 2020-12-01 08:00

    It's not particularly succinct, but I might use an extension method like this:

    public static IEnumerable<string> SplitByLength(this string s, int length)
    {
        for (int i = 0; i < s.Length; i += length)
        {
            if (i + length <= s.Length)
            {
                yield return s.Substring(i, length);
            }
            else
            {
                yield return s.Substring(i);
            }
        }
    }
    

    Note that I return an IEnumerable<string>, not an array. If you want to convert the result to an array, use ToArray:

    string[] arr = x.SplitByLength(3).ToArray();
    
    0 讨论(0)
提交回复
热议问题