Voici deux solutions possibles - une ligne LINQ traitant l'entrée de gauche à droite et un for
traditionnel -boucle traitant l'entrée de droite à gauche. La direction de traitement la plus rapide dépend de la longueur de la chaîne, de la longueur en octets autorisée, du nombre et de la distribution des caractères multi-octets et il est difficile de donner une suggestion générale. La décision entre LINQ et le code traditionnel est probablement une question de goût (ou peut-être de vitesse).
Si la vitesse compte, on pourrait penser à simplement accumuler la longueur en octets de chaque caractère jusqu'à atteindre la longueur maximale au lieu de calculer la longueur en octets de la chaîne entière à chaque itération. Mais je ne sais pas si cela fonctionnera car je ne connais pas assez bien l'encodage UTF-8. Je pourrais théoriquement imaginer que la longueur en octets d'une chaîne n'est pas égale à la somme des longueurs en octets de tous les caractères.
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;
}