C
C#5mo ago
Penthus

✅ Splitting string into chunks with delimiter

I am trying to split a string to fit within a character limit for my message. This works but cuts words, I was wondering if there is a way to have the chunk split in a way splits the chunk before a word on the new line. Example data is
John
Ben
Amy
Susan
Bob
Sarah
John
Ben
Amy
Susan
Bob
Sarah
Current result
John
Ben
Amy
Susan

B
ob
Sarah
John
Ben
Amy
Susan

B
ob
Sarah
Desired Result
John
Ben
Amy
Susan

Bob
Sarah
John
Ben
Amy
Susan

Bob
Sarah
Current Code
foreach (var member in members)
{
description += $"{member}\n";
}

if (description.Length < 4096)
{
var message = description;

PostMessage(message);
}
else if (description.Length > 4096)
{
var result = description.Chunk(4096).Select(x => new string(x)).ToList();
foreach (var content in result)
{
PostMessage(message);
}
}
foreach (var member in members)
{
description += $"{member}\n";
}

if (description.Length < 4096)
{
var message = description;

PostMessage(message);
}
else if (description.Length > 4096)
{
var result = description.Chunk(4096).Select(x => new string(x)).ToList();
foreach (var content in result)
{
PostMessage(message);
}
}
5 Replies
Omnissiah
Omnissiah5mo ago
you could for example cut the source to Nmax chars and then cut to the last new line (or delimiter) but there are many ways to do it
Pobiega
Pobiega5mo ago
var data = """
John
Ben
Amy
Susan
Bob
Sarah
""";

var result = ChunkWithLength(data, 9, "\n");

var output = string.Join("\n\n", result.Select(x => string.Join("\n", x)));
Console.WriteLine(output);

IEnumerable<IEnumerable<string>> ChunkWithLength(string data, int length, string delimiter)
{
var lines = data.Split(delimiter, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
var chunk = new List<string>();
var chunkSize = 0;
foreach (var line in lines)
{
var newSize = chunkSize + line.Length;

if (newSize > length)
{
yield return chunk;
chunk = [line];
chunkSize = line.Length;
}
else
{
chunk.Add(line);
chunkSize = newSize;
}
}

if (chunk.Count > 0)
{
yield return chunk;
}
}
var data = """
John
Ben
Amy
Susan
Bob
Sarah
""";

var result = ChunkWithLength(data, 9, "\n");

var output = string.Join("\n\n", result.Select(x => string.Join("\n", x)));
Console.WriteLine(output);

IEnumerable<IEnumerable<string>> ChunkWithLength(string data, int length, string delimiter)
{
var lines = data.Split(delimiter, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
var chunk = new List<string>();
var chunkSize = 0;
foreach (var line in lines)
{
var newSize = chunkSize + line.Length;

if (newSize > length)
{
yield return chunk;
chunk = [line];
chunkSize = line.Length;
}
else
{
chunk.Add(line);
chunkSize = newSize;
}
}

if (chunk.Count > 0)
{
yield return chunk;
}
}
certainly not the most beautiful... also seems to be an off by one or something here 🙂 there we go, added some trimming and now it makes sense :p
Penthus
PenthusOP5mo ago
Worked perfectly, thank you very much 🙂
Pobiega
Pobiega5mo ago
it can probably be optimized a bit, but eh, it works 🙂 if you are happy, don't forget to $close
MODiX
MODiX5mo ago
If you have no further questions, please use /close to mark the forum thread as answered
Want results from more Discord servers?
Add your server