Misalkan saya punya string:
string str = "1111222233334444";
Bagaimana saya bisa memecah string ini menjadi beberapa ukuran?
misalnya, memecah ini menjadi ukuran 4 akan menghasilkan string:
"1111"
"2222"
"3333"
"4444"
Misalkan saya punya string:
string str = "1111222233334444";
Bagaimana saya bisa memecah string ini menjadi beberapa ukuran?
misalnya, memecah ini menjadi ukuran 4 akan menghasilkan string:
"1111"
"2222"
"3333"
"4444"
Jawaban:
static IEnumerable<string> Split(string str, int chunkSize)
{
return Enumerable.Range(0, str.Length / chunkSize)
.Select(i => str.Substring(i * chunkSize, chunkSize));
}
Harap dicatat bahwa kode tambahan mungkin diperlukan untuk menangani case edge dengan anggun ( null
atau mengosongkan string input,, chunkSize == 0
panjang string input tidak dapat dibagi oleh chunkSize
, dll.). Pertanyaan asli tidak menentukan persyaratan untuk kasus tepi ini dan dalam kehidupan nyata persyaratan mungkin bervariasi sehingga mereka berada di luar cakupan jawaban ini.
(i * chunkSize + chunkSize <= str.Length) ? chunkSize : str.Length - i * chunkSize
. Masalah tambahan adalah bahwa fungsi ini tidak memperhitungkan str menjadi nol. Ini bisa diperbaiki dengan membungkus pernyataan kembali seluruh dalam ekspresi terner lain: (str != null) ? ... : Enumerable.Empty<String>();
.
str.Length / chunkSize
kedouble length = str.Length; double size = chunkSize; int count = (int)Math.Ceiling(length/size); return Enumerable.Range(0, count)...
StringLength % 4 will always be 0
. Jika Linq
tidak mudah dipahami maka ada jawaban lain yang menggunakan loop dan hasil. Siapa pun bebas memilih solusi yang paling disukainya. Anda dapat memposting kode Anda sebagai jawaban dan orang-orang akan dengan senang hati memilihnya.
Dalam kombinasi jawaban dove + Konstatin ...
static IEnumerable<string> WholeChunks(string str, int chunkSize) {
for (int i = 0; i < str.Length; i += chunkSize)
yield return str.Substring(i, chunkSize);
}
Ini akan bekerja untuk semua string yang dapat dipecah menjadi sejumlah besar potongan, dan akan melemparkan pengecualian.
Jika Anda ingin mendukung string dengan panjang apa pun, Anda dapat menggunakan kode berikut:
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));
}
Namun, OP secara eksplisit menyatakan dia tidak membutuhkan ini; itu agak lebih panjang dan sulit dibaca, sedikit lebih lambat. Dalam semangat KISS dan YAGNI, saya akan memilih opsi pertama: itu mungkin implementasi yang seefisien mungkin, dan sangat singkat, mudah dibaca, dan, yang penting, melempar pengecualian untuk input yang tidak sesuai.
Kenapa tidak loop? Inilah sesuatu yang akan melakukannya dengan cukup baik:
string str = "111122223333444455";
int chunkSize = 4;
int stringLength = str.Length;
for (int i = 0; i < stringLength ; i += chunkSize)
{
if (i + chunkSize > stringLength) chunkSize = stringLength - i;
Console.WriteLine(str.Substring(i, chunkSize));
}
Console.ReadLine();
Saya tidak tahu bagaimana Anda akan berurusan dengan kasus di mana string bukan faktor 4, tetapi tidak mengatakan Anda ide tidak mungkin, hanya bertanya-tanya motivasi untuk itu jika sederhana untuk loop melakukannya dengan sangat baik? Jelas di atas bisa dibersihkan dan bahkan dimasukkan sebagai metode perpanjangan.
Atau seperti yang disebutkan dalam komentar, Anda tahu itu / 4 lalu
str = "1111222233334444";
for (int i = 0; i < stringLength; i += chunkSize)
{Console.WriteLine(str.Substring(i, chunkSize));}
int chunkSize = 4
keluar dari loop. Itu hanya akan dimodifikasi pada pass terakhir.
i += chunkSize
sebagai gantinya.
str.Length
keluar dari loop dan ke dalam variabel lokal. Pengoptimal C # mungkin dapat inline panjang array, tapi saya pikir kode seperti yang tertulis akan melakukan pemanggilan metode pada setiap loop, yang tidak efisien, karena ukuran str
tidak pernah berubah.
Menggunakan ekspresi reguler dan Linq :
List<string> groups = (from Match m in Regex.Matches(str, @"\d{4}")
select m.Value).ToList();
Saya menemukan ini lebih mudah dibaca, tetapi itu hanya pendapat pribadi. Ini juga bisa menjadi satu-baris:).
\d
kelas karakter dengan a .
dan untuk menentukan RegexOptions.Singleline
.
Ini didasarkan pada solusi @dove tetapi diimplementasikan sebagai metode ekstensi.
Manfaat:
Kode
public static class EnumerableEx
{
public static IEnumerable<string> SplitBy(this string str, int chunkLength)
{
if (String.IsNullOrEmpty(str)) throw new ArgumentException();
if (chunkLength < 1) throw new ArgumentException();
for (int i = 0; i < str.Length; i += chunkLength)
{
if (chunkLength + i > str.Length)
chunkLength = str.Length - i;
yield return str.Substring(i, chunkLength);
}
}
}
Pemakaian
var result = "bobjoecat".SplitBy(3); // bob, joe, cat
Tes unit dihapus karena singkatnya (lihat revisi sebelumnya )
if (str.Length == 0) yield return String.Empty; else { for... }
IEnumerable
array, terutama tidak secara implisit.
Chunkify
.. Itu bukan milik saya, saya tidak ingat di mana saya melihat nama itu, tetapi rasanya sangat menyenangkan bagi saya
Bagaimana ini untuk satu-liner?
List<string> result = new List<string>(Regex.Split(target, @"(?<=\G.{4})", RegexOptions.Singleline));
Dengan regex ini tidak masalah jika potongan terakhir kurang dari empat karakter, karena hanya pernah melihat karakter di belakangnya.
Saya yakin ini bukan solusi yang paling efisien, tetapi saya harus membuangnya di sana.
target.Lenght % ChunckSize == 0
itu mengembalikan baris kosong tambahan misalnyaList<string> result = new List<string>(Regex.Split("fooo", @"(?<=\G.{4})", RegexOptions.Singleline));
Itu tidak cantik dan tidak cepat, tetapi bekerja, ini satu-liner dan itu 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();
ToCharArray
tidak perlu karena string
itu IEnumerable<char>
.
Baru-baru ini saya harus menulis sesuatu yang menyelesaikan ini di tempat kerja, jadi saya pikir saya akan memposting solusi saya untuk masalah ini. Sebagai bonus tambahan, fungsionalitas dari solusi ini menyediakan cara untuk membagi string ke arah yang berlawanan dan itu benar menangani karakter unicode seperti yang disebutkan sebelumnya oleh Marvin Pinto di atas. Jadi begini:
using System;
using Extensions;
namespace TestCSharp
{
class Program
{
static void Main(string[] args)
{
string asciiStr = "This is a string.";
string unicodeStr = "これは文字列です。";
string[] array1 = asciiStr.Split(4);
string[] array2 = asciiStr.Split(-4);
string[] array3 = asciiStr.Split(7);
string[] array4 = asciiStr.Split(-7);
string[] array5 = unicodeStr.Split(5);
string[] array6 = unicodeStr.Split(-5);
}
}
}
namespace Extensions
{
public static class StringExtensions
{
/// <summary>Returns a string array that contains the substrings in this string that are seperated a given fixed length.</summary>
/// <param name="s">This string object.</param>
/// <param name="length">Size of each substring.
/// <para>CASE: length > 0 , RESULT: String is split from left to right.</para>
/// <para>CASE: length == 0 , RESULT: String is returned as the only entry in the array.</para>
/// <para>CASE: length < 0 , RESULT: String is split from right to left.</para>
/// </param>
/// <returns>String array that has been split into substrings of equal length.</returns>
/// <example>
/// <code>
/// string s = "1234567890";
/// string[] a = s.Split(4); // a == { "1234", "5678", "90" }
/// </code>
/// </example>
public static string[] Split(this string s, int length)
{
System.Globalization.StringInfo str = new System.Globalization.StringInfo(s);
int lengthAbs = Math.Abs(length);
if (str == null || str.LengthInTextElements == 0 || lengthAbs == 0 || str.LengthInTextElements <= lengthAbs)
return new string[] { str.ToString() };
string[] array = new string[(str.LengthInTextElements % lengthAbs == 0 ? str.LengthInTextElements / lengthAbs: (str.LengthInTextElements / lengthAbs) + 1)];
if (length > 0)
for (int iStr = 0, iArray = 0; iStr < str.LengthInTextElements && iArray < array.Length; iStr += lengthAbs, iArray++)
array[iArray] = str.SubstringByTextElements(iStr, (str.LengthInTextElements - iStr < lengthAbs ? str.LengthInTextElements - iStr : lengthAbs));
else // if (length < 0)
for (int iStr = str.LengthInTextElements - 1, iArray = array.Length - 1; iStr >= 0 && iArray >= 0; iStr -= lengthAbs, iArray--)
array[iArray] = str.SubstringByTextElements((iStr - lengthAbs < 0 ? 0 : iStr - lengthAbs + 1), (iStr - lengthAbs < 0 ? iStr + 1 : lengthAbs));
return array;
}
}
}
Juga, di sini adalah tautan gambar ke hasil menjalankan kode ini: http://i.imgur.com/16Iih.png
{str.ToString()}
di akhir pernyataan IF pertama Anda. Apakah Anda yakin tidak bermaksud jahat str.String
? Saya punya masalah dengan kode di atas, membuat perubahan itu, dan semuanya berfungsi.
Ini harus jauh lebih cepat dan lebih efisien daripada menggunakan LINQ atau pendekatan lain yang digunakan di sini.
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);
}
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;
}
Anda dapat menggunakan morelinq oleh Jon Skeet. Gunakan Batch seperti:
string str = "1111222233334444";
int chunkSize = 4;
var chunks = str.Batch(chunkSize).Select(r => new String(r.ToArray()));
Ini akan mengembalikan 4 potongan untuk string "1111222233334444"
. Jika panjang string kurang dari atau sama dengan ukuran chunkBatch
akan mengembalikan string sebagai satu-satunya elemenIEnumerable<string>
Untuk output:
foreach (var chunk in chunks)
{
Console.WriteLine(chunk);
}
dan itu akan memberi:
1111
2222
3333
4444
static IEnumerable<string> Split(string str, double chunkSize)
{
return Enumerable.Range(0, (int) Math.Ceiling(str.Length/chunkSize))
.Select(i => new string(str
.Skip(i * (int)chunkSize)
.Take((int)chunkSize)
.ToArray()));
}
dan pendekatan lain:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
var x = "Hello World";
foreach(var i in x.ChunkString(2)) Console.WriteLine(i);
}
}
public static class Ext{
public static IEnumerable<string> ChunkString(this string val, int chunkSize){
return val.Select((x,i) => new {Index = i, Value = x})
.GroupBy(x => x.Index/chunkSize, x => x.Value)
.Select(x => string.Join("",x));
}
}
Enam tahun kemudian o_O
Hanya karena
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)));
}
atau
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 semua kasus tepi ditangani.
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
static IEnumerable<string> Split(string str, int chunkSize)
{
IEnumerable<string> retVal = Enumerable.Range(0, str.Length / chunkSize)
.Select(i => str.Substring(i * chunkSize, chunkSize))
if (str.Length % chunkSize > 0)
retVal = retVal.Append(str.Substring(str.Length / chunkSize * chunkSize, str.Length % chunkSize));
return retVal;
}
Itu benar menangani panjang string input tidak dapat dibagi oleh chunkSize.
Harap dicatat bahwa kode tambahan mungkin diperlukan untuk menangani kasus tepi dengan anggun (null atau string input kosong, chunkSize == 0).
Tip penting jika string yang sedang dipotong perlu untuk mendukung semua karakter Unicode.
Jika string ini untuk mendukung karakter internasional seperti 𠀋
, maka pisahkan string menggunakan kelas System.Globalization.StringInfo. Menggunakan StringInfo, Anda dapat membagi string berdasarkan jumlah elemen teks.
string internationalString = '𠀋';
String di atas memiliki Panjang 2, karena String.Length
properti mengembalikan jumlah objek Char dalam contoh ini, bukan jumlah karakter Unicode.
Jawaban Terbaik, Termudah dan Umum :).
string originalString = "1111222233334444";
List<string> test = new List<string>();
int chunkSize = 4; // change 4 with the size of strings you want.
for (int i = 0; i < originalString.Length; i = i + chunkSize)
{
if (originalString.Length - i >= chunkSize)
test.Add(originalString.Substring(i, chunkSize));
else
test.Add(originalString.Substring(i,((originalString.Length - i))));
}
Substring
overload yang tidak memerlukan parameter panjang originalString.Substring(i)
. Anda juga bisa menggunakannya >
sebagai ganti >=
cek Anda.
Secara pribadi saya lebih suka solusi saya :-)
Ini menangani:
Ini diimplementasikan sebagai metode ekstensi, dan menghitung jumlah potongan yang akan dihasilkan sebelumnya. Ini memeriksa potongan terakhir karena jika panjang teks tidak banyak itu perlu lebih pendek. Bersih, pendek, mudah dimengerti ... dan berfungsi!
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;
}
List<string> SplitString(int chunk, string input)
{
List<string> list = new List<string>();
int cycles = input.Length / chunk;
if (input.Length % chunk != 0)
cycles++;
for (int i = 0; i < cycles; i++)
{
try
{
list.Add(input.Substring(i * chunk, chunk));
}
catch
{
list.Add(input.Substring(i * chunk));
}
}
return list;
}
Saya pikir ini adalah jawaban langsung:
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);
}
}
Dan itu mencakup kasus tepi.
Saya tahu pertanyaan sudah berumur bertahun-tahun, tetapi ini adalah implementasi Rx. Ini menangani length % chunkSize != 0
masalah di luar kotak:
public static IEnumerable<string> Chunkify(this string input, int size)
{
if(size < 1)
throw new ArgumentException("size must be greater than 0");
return input.ToCharArray()
.ToObservable()
.Buffer(size)
.Select(x => new string(x.ToArray()))
.ToEnumerable();
}
Saya sedikit membangun solusi João. Apa yang saya lakukan secara berbeda adalah dalam metode saya, Anda benar-benar dapat menentukan apakah Anda ingin mengembalikan array dengan karakter yang tersisa atau apakah Anda ingin memotongnya jika karakter akhir tidak cocok dengan panjang chunk yang diperlukan, saya pikir itu cukup fleksibel dan kode cukup mudah:
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;
}
}
}
public static List<string> SplitByMaxLength(this string str)
{
List<string> splitString = new List<string>();
for (int index = 0; index < str.Length; index += MaxLength)
{
splitString.Add(str.Substring(index, Math.Min(MaxLength, str.Length - index)));
}
return splitString;
}
Berubah sedikit untuk mengembalikan bagian yang ukurannya tidak sama dengan chunkSize
public static IEnumerable<string> Split(this string str, int chunkSize)
{
var splits = new List<string>();
if (str.Length < chunkSize) { chunkSize = str.Length; }
splits.AddRange(Enumerable.Range(0, str.Length / chunkSize).Select(i => str.Substring(i * chunkSize, chunkSize)));
splits.Add(str.Length % chunkSize > 0 ? str.Substring((str.Length / chunkSize) * chunkSize, str.Length - ((str.Length / chunkSize) * chunkSize)) : string.Empty);
return (IEnumerable<string>)splits;
}
List
untuk IEnumerable
; semua yang dilakukan adalah menyembunyikan fungsi khusus Daftar yang mungkin ingin Anda gunakan. Tidak ada kerugian apa pun untuk hanya mengembalikan List
.
Saya tidak ingat siapa yang memberi saya ini, tetapi itu bekerja dengan baik. Saya mempercepat menguji sejumlah cara untuk memecah tipe Enumerable ke dalam kelompok. Penggunaannya akan seperti ini ...
List<string> Divided = Source3.Chunk(24).Select(Piece => string.Concat<char>(Piece)).ToList();
Kode ekstensi akan terlihat seperti ini ...
#region Chunk Logic
private class ChunkedEnumerable<T> : IEnumerable<T>
{
class ChildEnumerator : IEnumerator<T>
{
ChunkedEnumerable<T> parent;
int position;
bool done = false;
T current;
public ChildEnumerator(ChunkedEnumerable<T> parent)
{
this.parent = parent;
position = -1;
parent.wrapper.AddRef();
}
public T Current
{
get
{
if (position == -1 || done)
{
throw new InvalidOperationException();
}
return current;
}
}
public void Dispose()
{
if (!done)
{
done = true;
parent.wrapper.RemoveRef();
}
}
object System.Collections.IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
position++;
if (position + 1 > parent.chunkSize)
{
done = true;
}
if (!done)
{
done = !parent.wrapper.Get(position + parent.start, out current);
}
return !done;
}
public void Reset()
{
// per http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.reset.aspx
throw new NotSupportedException();
}
}
EnumeratorWrapper<T> wrapper;
int chunkSize;
int start;
public ChunkedEnumerable(EnumeratorWrapper<T> wrapper, int chunkSize, int start)
{
this.wrapper = wrapper;
this.chunkSize = chunkSize;
this.start = start;
}
public IEnumerator<T> GetEnumerator()
{
return new ChildEnumerator(this);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
private class EnumeratorWrapper<T>
{
public EnumeratorWrapper(IEnumerable<T> source)
{
SourceEumerable = source;
}
IEnumerable<T> SourceEumerable { get; set; }
Enumeration currentEnumeration;
class Enumeration
{
public IEnumerator<T> Source { get; set; }
public int Position { get; set; }
public bool AtEnd { get; set; }
}
public bool Get(int pos, out T item)
{
if (currentEnumeration != null && currentEnumeration.Position > pos)
{
currentEnumeration.Source.Dispose();
currentEnumeration = null;
}
if (currentEnumeration == null)
{
currentEnumeration = new Enumeration { Position = -1, Source = SourceEumerable.GetEnumerator(), AtEnd = false };
}
item = default(T);
if (currentEnumeration.AtEnd)
{
return false;
}
while (currentEnumeration.Position < pos)
{
currentEnumeration.AtEnd = !currentEnumeration.Source.MoveNext();
currentEnumeration.Position++;
if (currentEnumeration.AtEnd)
{
return false;
}
}
item = currentEnumeration.Source.Current;
return true;
}
int refs = 0;
// needed for dispose semantics
public void AddRef()
{
refs++;
}
public void RemoveRef()
{
refs--;
if (refs == 0 && currentEnumeration != null)
{
var copy = currentEnumeration;
currentEnumeration = null;
copy.Source.Dispose();
}
}
}
/// <summary>Speed Checked. Works Great!</summary>
public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int chunksize)
{
if (chunksize < 1) throw new InvalidOperationException();
var wrapper = new EnumeratorWrapper<T>(source);
int currentPos = 0;
T ignore;
try
{
wrapper.AddRef();
while (wrapper.Get(currentPos, out ignore))
{
yield return new ChunkedEnumerable<T>(wrapper, chunksize, currentPos);
currentPos += chunksize;
}
}
finally
{
wrapper.RemoveRef();
}
}
#endregion
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;
}
}
i += offSet
ke for
ekspresi Anda .
Modified (sekarang menerima setiap non nol string
dan setiap positif chunkSize
) Konstantin Spirin 's solusi:
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));
}
Tes:
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));
static List<string> GetChunks(string value, int chunkLength)
{
var res = new List<string>();
int count = (value.Length / chunkLength) + (value.Length % chunkLength > 0 ? 1 : 0);
Enumerable.Range(0, count).ToList().ForEach(f => res.Add(value.Skip(f * chunkLength).Take(chunkLength).Select(z => z.ToString()).Aggregate((a,b) => a+b)));
return res;
}
Berdasarkan jawaban poster lainnya, bersama dengan beberapa contoh penggunaan:
public static string FormatSortCode(string sortCode)
{
return ChunkString(sortCode, 2, "-");
}
public static string FormatIBAN(string iban)
{
return ChunkString(iban, 4, " ");
}
private static string ChunkString(string str, int chunkSize, string separator)
{
var b = new StringBuilder();
var stringLength = str.Length;
for (var i = 0; i < stringLength; i += chunkSize)
{
if (i + chunkSize > stringLength) chunkSize = stringLength - i;
b.Append(str.Substring(i, chunkSize));
if (i+chunkSize != stringLength)
b.Append(separator);
}
return b.ToString();
}
Menggunakan ekstensi Buffer dari perpustakaan IX
static IEnumerable<string> Split( this string str, int chunkSize )
{
return str.Buffer(chunkSize).Select(l => String.Concat(l));
}