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

Time:02-05

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.

CodePudding user response:

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;
}

CodePudding user response:

I like the answer by Mathias R. Jessen as it is efficient and clean.

Just thought I'd show how to do it using the List<> as in your original attempt:

static public string[] Trim(string[] arr)
{
    List<string> TrimmedArray = new List<string>(arr);
    while (TrimmedArray.Count>0 && String.IsEmpty(TrimmedArray[0]))
    {
        TrimmedArray.RemoveAt(0);            
    }
    while (TrimmedArray.Count>0 && String.IsEmpty(TrimmedArray[TrimmedArray.Count - 1]))
    {
        TrimmedArray.RemoveAt(TrimmedArray.Count - 1);
    }
    return TrimmedArray.ToArray();
}

This is not as efficient as the other answer since the internal array within the List<> has to shift all its elements to the left each time an element is deleted from the front.

  •  Tags:  
  • Related