Zde jsou dvě možná řešení – LINQ one-liner zpracovávající vstup zleva doprava a tradiční for
-smyčka zpracovává vstup zprava doleva. Který směr zpracování je rychlejší, závisí na délce řetězce, povolené délce bajtu a počtu a distribuci vícebajtových znaků a je těžké dát obecný návrh. Rozhodnutí mezi LINQ a tradičním kódem je pravděpodobně věcí vkusu (nebo možná rychlosti).
Pokud záleží na rychlosti, dalo by se uvažovat o pouhém sčítání délky bajtů každého znaku až do dosažení maximální délky namísto výpočtu délky bajtů celého řetězce v každé iteraci. Ale nejsem si jistý, jestli to bude fungovat, protože neznám dostatečně dobře kódování UTF-8. Dovedl bych si teoreticky představit, že bytová délka řetězce se nerovná součtu bajtových délek všech znaků.
public static String LimitByteLength(String input, Int32 maxLength)
{
return new String(input
.TakeWhile((c, i) =>
Encoding.UTF8.GetByteCount(input.Substring(0, i + 1)) <= maxLength)
.ToArray());
}
public static String LimitByteLength2(String input, Int32 maxLength)
{
for (Int32 i = input.Length - 1; i >= 0; i--)
{
if (Encoding.UTF8.GetByteCount(input.Substring(0, i + 1)) <= maxLength)
{
return input.Substring(0, i + 1);
}
}
return String.Empty;
}