Advertisement
Advertisement


How do I truncate a .NET string?


Question

I would like to truncate a string such that its length is not longer than a given value. I am writing to a database table and want to ensure that the values I write meet the constraint of the column's datatype.

For instance, it would be nice if I could write the following:

string NormalizeLength(string value, int maxLength)
{
    return value.Substring(0, maxLength);
}

Unfortunately, this raises an exception because maxLength generally exceeds the boundaries of the string value. Of course, I could write a function like the following, but I was hoping that something like this already exists.

string NormalizeLength(string value, int maxLength)
{
    return value.Length <= maxLength ? value : value.Substring(0, maxLength);
} 

Where is the elusive API that performs this task? Is there one?

2017/12/17
1
421
12/17/2017 12:40:41 AM

Accepted Answer

There isn't a Truncate() method on string, unfortunately. You have to write this kind of logic yourself. What you can do, however, is wrap this in an extension method so you don't have to duplicate it everywhere:

public static class StringExt
{
    public static string Truncate(this string value, int maxLength)
    {
        if (string.IsNullOrEmpty(value)) return value;
        return value.Length <= maxLength ? value : value.Substring(0, maxLength); 
    }
}

Now we can write:

var someString = "...";
someString = someString.Truncate(2);
2014/01/20
638
1/20/2014 9:12:53 PM

Or instead of the ternary operator, you could use Math.min

public static class StringExt
{
    public static string Truncate( this string value, int maxLength )
    {
        if (string.IsNullOrEmpty(value)) { return value; }

        return value.Substring(0, Math.Min(value.Length, maxLength));
    }
}
2012/12/19

I figured I would throw in my implementation since I believe it covers all of the cases that have been touched on by the others and does so in a concise way that is still readable.

public static string Truncate(this string value, int maxLength)
{
    if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
    {
        return value.Substring(0, maxLength);
    }

    return value;
}

This solution mainly builds upon the Ray's solution and opens up the method for use as an extension method by using the this keyword just as LBushkin does in his solution.

2018/01/31

Because performance testing is fun: (using linqpad extension methods)

var val = string.Concat(Enumerable.Range(0, 50).Select(i => i % 10));

foreach(var limit in new[] { 10, 25, 44, 64 })
    new Perf<string> {
        { "newstring" + limit, n => new string(val.Take(limit).ToArray()) },
        { "concat" + limit, n => string.Concat(val.Take(limit)) },
        { "truncate" + limit, n => val.Substring(0, Math.Min(val.Length, limit)) },
        { "smart-trunc" + limit, n => val.Length <= limit ? val : val.Substring(0, limit) },
        { "stringbuilder" + limit, n => new StringBuilder(val, 0, Math.Min(val.Length, limit), limit).ToString() },
    }.Vs();

The truncate method was "significantly" faster. #microoptimization

Early

  • truncate10 5788 ticks elapsed (0.5788 ms) [in 10K reps, 5.788E-05 ms per]
  • smart-trunc10 8206 ticks elapsed (0.8206 ms) [in 10K reps, 8.206E-05 ms per]
  • stringbuilder10 10557 ticks elapsed (1.0557 ms) [in 10K reps, 0.00010557 ms per]
  • concat10 45495 ticks elapsed (4.5495 ms) [in 10K reps, 0.00045495 ms per]
  • newstring10 72535 ticks elapsed (7.2535 ms) [in 10K reps, 0.00072535 ms per]

Late

  • truncate44 8835 ticks elapsed (0.8835 ms) [in 10K reps, 8.835E-05 ms per]
  • stringbuilder44 13106 ticks elapsed (1.3106 ms) [in 10K reps, 0.00013106 ms per]
  • smart-trunc44 14821 ticks elapsed (1.4821 ms) [in 10K reps, 0.00014821 ms per]
  • newstring44 144324 ticks elapsed (14.4324 ms) [in 10K reps, 0.00144324 ms per]
  • concat44 174610 ticks elapsed (17.461 ms) [in 10K reps, 0.0017461 ms per]

Too Long

  • smart-trunc64 6944 ticks elapsed (0.6944 ms) [in 10K reps, 6.944E-05 ms per]
  • truncate64 7686 ticks elapsed (0.7686 ms) [in 10K reps, 7.686E-05 ms per]
  • stringbuilder64 13314 ticks elapsed (1.3314 ms) [in 10K reps, 0.00013314 ms per]
  • newstring64 177481 ticks elapsed (17.7481 ms) [in 10K reps, 0.00177481 ms per]
  • concat64 241601 ticks elapsed (24.1601 ms) [in 10K reps, 0.00241601 ms per]
2017/09/06

In .NET 4.0 you can use the Take method:

string.Concat(myString.Take(maxLength));

Not tested for efficiency!

2016/05/18

You could use LINQ... it eliminates the need to check string length. Admittedly maybe not the most efficient, but it's fun.

string result = string.Join("", value.Take(maxLength)); // .NET 4 Join

or

string result = new string(value.Take(maxLength).ToArray());
2010/05/05

Source: https://stackoverflow.com/questions/2776673
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]