Search code examples
c#arraystrim

How to Trim the Leading and Trailing White-Spaces of a String Array in C#


I want to trim all the white-spaces and empty strings only from the starting and ending of an array without converting it into a string in C#.

This is what I've done so far to solve my problem but I'm looking for a bit more efficient solution as I don't want to be stuck with a just works solution to the prob

static public string[] Trim(string[] arr)
{
    List<string> TrimmedArray = new List<string>(arr);
    foreach (string i in TrimmedArray.ToArray())
    {
        if (String.IsEmpty(i)) TrimmedArray.RemoveAt(TrimmedArray.IndexOf(i));
        else break;
    }
    
    foreach (string i in TrimmedArray.ToArray().Reverse())
    {
        if (String.IsEmpty(i)) TrimmedArray.RemoveAt(TrimmedArray.IndexOf(i));
        else break;
    }
    
    return TrimmedArray.ToArray();
}

NOTE: String.IsEmpty is a custom function which check whether a string was NULL, Empty or just a White-Space.


Solution

  • Your code allocates a lot of new arrays unnecessarily. When you instantiate a list from an array, the list creates a new backing array to store the items, and every time you call ToArray() on the resulting list, you're also allocating yet another copy.

    The second problem is with TrimmedArray.RemoveAt(TrimmedArray.IndexOf(i)) - if the array contains multiple copies of the same string value in the middle as at the end, you might end up removing strings from the middle.

    My advice would be split the problem into two distinct steps:

    • Find both boundary indices (the first and last non-empty strings in the array)
    • Copy only the relevant middle-section to a new array.

    To locate the boundary indices you can use Array.FindIndex() and Array.FindLastIndex():

    static public string[] Trim(string[] arr)
    {
        if(arr == null || arr.Length == 0)
            // no need to search through nothing
            return Array.Empty<string>();
    
        // define predicate to test for non-empty strings
        Predicate<string> IsNotEmpty = string s => !String.IsEmpty(str);
    
        var firstIndex = Array.FindIndex(arr, IsNotEmpty);
    
        if(firstIndex < 0)
            // nothing to return if it's all whitespace anyway
            return Array.Empty<string>();
    
        var lastIndex = Array.FindLastIndex(arr, IsNotEmpty);
    
        // calculate size of the relevant middle-section from the indices
        var newArraySize = lastIndex - firstIndex + 1;
    
        // create new array and copy items to it
        var results = new string[newArraySize];
        Array.Copy(arr, firstIndex, results, 0, newArraySize);
    
        return results;
    }