假设我有一个字符串:
string str = "1111222233334444";
我如何把这个字符串分成一定大小的块?
例如,将它分解为4的大小将返回字符串:
"1111"
"2222"
"3333"
"4444"
假设我有一个字符串:
string str = "1111222233334444";
我如何把这个字符串分成一定大小的块?
例如,将它分解为4的大小将返回字符串:
"1111"
"2222"
"3333"
"4444"
当前回答
我认为这是一个直截了当的答案:
public static IEnumerable<string> Split(this string str, int chunkSize)
{
if(string.IsNullOrEmpty(str) || chunkSize<1)
throw new ArgumentException("String can not be null or empty and chunk size should be greater than zero.");
var chunkCount = str.Length / chunkSize + (str.Length % chunkSize != 0 ? 1 : 0);
for (var i = 0; i < chunkCount; i++)
{
var startIndex = i * chunkSize;
if (startIndex + chunkSize >= str.Length)
yield return str.Substring(startIndex);
else
yield return str.Substring(startIndex, chunkSize);
}
}
它涵盖了边缘情况。
其他回答
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;
}
修改(现在它接受任何非空字符串和任何正chunkSize) Konstantin Spirin的解决方案:
public static IEnumerable<String> Split(String value, int chunkSize) {
if (null == value)
throw new ArgumentNullException("value");
else if (chunkSize <= 0)
throw new ArgumentOutOfRangeException("chunkSize", "Chunk size should be positive");
return Enumerable
.Range(0, value.Length / chunkSize + ((value.Length % chunkSize) == 0 ? 0 : 1))
.Select(index => (index + 1) * chunkSize < value.Length
? value.Substring(index * chunkSize, chunkSize)
: value.Substring(index * chunkSize));
}
测试:
String source = @"ABCDEF";
// "ABCD,EF"
String test1 = String.Join(",", Split(source, 4));
// "AB,CD,EF"
String test2 = String.Join(",", Split(source, 2));
// "ABCDEF"
String test3 = String.Join(",", Split(source, 123));
public static List<string> DevideByStringLength(string text, int chunkSize)
{
double a = (double)text.Length / chunkSize;
var numberOfChunks = Math.Ceiling(a);
Console.WriteLine($"{text.Length} | {numberOfChunks}");
List<string> chunkList = new List<string>();
for (int i = 0; i < numberOfChunks; i++)
{
string subString = string.Empty;
if (i == (numberOfChunks - 1))
{
subString = text.Substring(chunkSize * i, text.Length - chunkSize * i);
chunkList.Add(subString);
continue;
}
subString = text.Substring(chunkSize * i, chunkSize);
chunkList.Add(subString);
}
return chunkList;
}
我在João的解决方案基础上做了一些改进。 我所做的不同之处在于,在我的方法中,你实际上可以指定是否要返回带有剩余字符的数组,或者如果结束字符不匹配所需的块长度,你是否要截断它们,我认为这是相当灵活的,代码相当直接:
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace SplitFunction
{
class Program
{
static void Main(string[] args)
{
string text = "hello, how are you doing today?";
string[] chunks = SplitIntoChunks(text, 3,false);
if (chunks != null)
{
chunks.ToList().ForEach(e => Console.WriteLine(e));
}
Console.ReadKey();
}
private static string[] SplitIntoChunks(string text, int chunkSize, bool truncateRemaining)
{
string chunk = chunkSize.ToString();
string pattern = truncateRemaining ? ".{" + chunk + "}" : ".{1," + chunk + "}";
string[] chunks = null;
if (chunkSize > 0 && !String.IsNullOrEmpty(text))
chunks = (from Match m in Regex.Matches(text,pattern)select m.Value).ToArray();
return chunks;
}
}
}
我个人更喜欢我的解决方案:-)
它处理:
是块大小的倍数的字符串长度。 不是块大小倍数的字符串长度。 小于块大小的字符串长度。 NULL和空字符串(抛出异常)。 块大小小于1(引发异常)。
它是作为一个扩展方法实现的,它预先计算将要生成的块的数量。它检查最后一个块,因为如果文本长度不是一个倍数,它需要更短。干净、简短、容易理解……和工作!
public static string[] Split(this string value, int chunkSize)
{
if (string.IsNullOrEmpty(value)) throw new ArgumentException("The string cannot be null.");
if (chunkSize < 1) throw new ArgumentException("The chunk size should be equal or greater than one.");
int remainder;
int divResult = Math.DivRem(value.Length, chunkSize, out remainder);
int numberOfChunks = remainder > 0 ? divResult + 1 : divResult;
var result = new string[numberOfChunks];
int i = 0;
while (i < numberOfChunks - 1)
{
result[i] = value.Substring(i * chunkSize, chunkSize);
i++;
}
int lastChunkSize = remainder > 0 ? remainder : chunkSize;
result[i] = value.Substring(i * chunkSize, lastChunkSize);
return result;
}