如何 Trim C# 中字符串数组的前导和尾随空白

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

我想 trim 仅从数组的开头和结尾处删除所有空格和空字符串,而不是将其转换为 C# 中的字符串。

这是我迄今为止为解决问题所做的工作,但我正在寻找更有效的解决方案,因为我不想被一个可行的解决方案所困

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

注意:String.IsEmpty 是一个自定义函数,它检查字符串是否为 NULL、空或只是一个白色-Space.

您的代码不必要地分配了很多新数组。当您从一个数组实例化一个列表时,该列表会创建一个新的支持数组来存储项目,并且每次您在结果列表上调用 ToArray() 时,您还会分配另一个副本。

第二个问题是 TrimmedArray.RemoveAt(TrimmedArray.IndexOf(i)) - 如果数组在中间和末尾包含相同字符串值的多个副本,您可能最终会从中间删除字符串。

我的建议是将问题分为两个不同的步骤:

  • 找到两个边界索引(数组中第一个和最后一个 non-empty 字符串)
  • 只复制相关的 middle-section 到一个新数组。

要找到边界索引,您可以使用 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;
}

我喜欢 Mathias R. Jessen 的回答,因为它既高效又干净。

只是想我会像您最初尝试的那样使用 List<> 来展示如何做到这一点:

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

这不如其他答案有效,因为每次从前面删除一个元素时,List<> 中的内部数组必须将其所有元素向左移动。