考えられる解決策は次の2つです。入力を左から右に処理するLINQワンライナーと従来のfor
-入力を右から左にループ処理します。どちらの処理方向が速いかは、文字列の長さ、許可されるバイト長、およびマルチバイト文字の数と分布に依存し、一般的な提案をするのは困難です。 LINQと従来のコードのどちらを選ぶかは、おそらく好み(または速度)の問題です。
速度が重要な場合は、各反復で文字列全体のバイト長を計算するのではなく、最大長に達するまで各文字のバイト長を累積することを考えることができます。しかし、UTF-8エンコーディングについて十分に理解していないため、これが機能するかどうかはわかりません。理論的には、文字列のバイト長がすべての文字のバイト長の合計と等しくないことを想像できます。
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;
}