6

最简单的方法是什么?

结果应该是:

1: one
2: two
3: 
4:
5: five

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestLines8833
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> lines = new List<string>();
            lines.Add("");
            lines.Add("one");
            lines.Add("two");
            lines.Add("");
            lines.Add("");
            lines.Add("five");
            lines.Add("");
            lines.Add("");

            lines.TrimList();
        }
    }

    public static class Helpers
    {
        public static List<string> TrimList(this List<string> list)
        {
            //???
        }
    }
}
4

8 回答 8

9

好的,现在我了解了预期的结果:

public static class Helpers
{
    // Adjust this to use trimming, avoid nullity etc if you you want
    private static readonly Predicate<string> 
        NonBlankLinePredicate = x => x.Length != 0;

    public static List<string> TrimList(this List<string> list)
    {
        int start = list.FindIndex(NonBlankLinePredicate);
        int end = list.FindLastIndex(NonBlankLinePredicate);

        // Either start and end are both -1, or neither is
        if (start == -1)
        {
            return new List<string>();
        }
        return list.GetRange(start, end - start + 1);
    }
}

请注意,这不会更改现有列表 - 它会返回一个包含所需内容的新列表。鉴于您已为该方法提供了返回类型,但您的示例在不使用结果的情况下调用它,因此尚不清楚您想要什么行为。我个人更喜欢无副作用的方法,尽管更改名称可能值得:)

于 2010-02-24T10:37:44.927 回答
6

那这个呢:

    public static void TrimList(this List<string> list) {
        while (0 != list.Count && string.IsNullOrEmpty(list[0])) {
            list.RemoveAt(0);
        }
        while (0 != list.Count && string.IsNullOrEmpty(list[list.Count - 1])) {
            list.RemoveAt(list.Count - 1);
        }
    }

请注意,签名已与您的示例不同(返回类型为 void)。

于 2010-02-24T10:38:03.113 回答
5

试试这个:

public static List<string> TrimList(this List<string> list)  
    {  
        return list.SkipWhile(l => String.IsNullOrEmpty(l)).Reverse().SkipWhile(l => String.IsNullOrEmpty(l)).Reverse();
    } 
于 2010-02-24T10:42:50.607 回答
1

我知道的老问题,但这是一个扩展方法,它将使用 Linq 基于布尔委托从集合的开头和结尾修剪对象。

public static class IEnumerableExtensions
{
    public static IEnumerable<T> Trim<T>( this IEnumerable<T> collection, Func<T, bool> trimCondition )
    {
          return collection.SkipWhile( trimCondition ).Reverse().SkipWhile( trimCondition ).Reverse();
    }
}

您的案例示例:

lines.Trim(line => string.IsNullOrEmpty(line)); 
于 2014-06-26T23:12:41.810 回答
0

如果你想删除空字符串,你可以做这样的事情......

lines = lines.Where(s => ! string.IsNullOrEmpty(s)).ToList();

更新:抱歉刚刚看到您希望保留内部空白的编辑。

在这种情况下,我只会使用您上面提到的扩展方法,因为我认为没有更简单的方法可以做到这一点。

于 2010-02-24T10:35:54.463 回答
0

没有内置的东西可以做这样的特定事情。您可以从头到尾检查项目并删除空字符串。为了尽量减少对列表的操作(重复使用 RemoveAt 删除第一个项目是相当低效的),首先计算要删除的项目的数量,然后使用该RemoveRange方法一次将它们全部删除。

为了匹配您在代码中使用该方法的方式,扩展必须更改列表而不是返回新列表。

public static void TrimList(this List<string> list) {
  int cnt = 0;
  while (cnt < list.Count && list[cnt].Length == 0) cnt++;
  if (cnt > 0) list.RemoveRange(0, cnt);
  cnt = 0;
  while (cnt < list.Count - 1 && list[list.Count - cnt - 1].Length == 0) cnt++;
  if (cnt > 0) list.RemoveRange(list.Count - cnt, cnt);
}
于 2010-02-24T10:42:15.133 回答
0

有时,从可读性和性能的角度来看,旧的 foreach 胜过 linq:

public static List<string> TrimList(this List<string> list)
{
    list.TrimListStart();
    vat l = list.Reverse().ToList();
    l.TrimListStart();
    return l;
}

public void TrimListStart(this List<string> list)
{
    foreach(var s in new List(list))
    {
        if(string.string.IsNullOrWhiteSpace(s))
        {
            list.Remove(s);
        }
        else
        {
            break;
        }
    }
}
于 2010-02-24T10:44:20.983 回答
0
    int start = stringList.FindIndex((i => i.Trim() != ""));
    int end = stringList.FindLastIndex((i => i.Trim() != ""));
    List<string> range = new List<string>();
    if(start != -1 && end != -1)
        range = stringList.GetRange(start, (end - start + 1));
于 2010-02-24T10:46:20.527 回答