修剪列表的最佳方法是什么?

时间:2014-09-12 00:28:39

标签: c# linq collections

我有一个字符串列表。它是在其他地方生成的,但我将在下面生成它以帮助描述这个简化的例子

var list = new List<string>();
list.Add("Joe");
list.Add("");
list.Add("Bill");
list.Add("Bill");
list.Add("");
list.Add("Scott");
list.Add("Joe");
list.Add("");
list.Add("");

list = TrimList(list);

我想要一个函数"trims"这个列表和修饰我想要删除数组末尾的所有项目是空字符串(在本例中是最后两个)。

注意:我仍然希望保留数组中第二个项目的空白(或任何其他不在最后的项目),这样我就无法做到.Where(r=> String.isNullOrEmpty(r))

5 个答案:

答案 0 :(得分:9)

我会写它没有任何LINQ,说实话 - 毕竟,你正在修改一个集合,而不仅仅是查询它:

void TrimList(List<string> list)
{
    int lastNonEmpty = list.FindLastIndex(x => !string.IsNullOrEmpty(x));
    int firstToRemove = lastNonEmpty + 1;
    list.RemoveRange(firstToRemove, list.Count - firstToRemove);
}

如果你真的想创建一个 new 列表,那么基于LINQ的解决方案是可以的......虽然可能有些效率低下(因为Reverse必须缓冲所有内容)。

答案 1 :(得分:3)

利用ReverseSkipWhile

list = list.Reverse().SkipWhile(s => String.IsNullOrEmpty(s)).Reverse().ToList();

答案 2 :(得分:1)

List<T>(不是界面)有FindLastIndex方法。因此,您可以将其包装在方法中:

static IList<string> TrimList(List<string> input) {
    return input.Take(input.FindLastIndex(x => !string.IsNullOrEmpty(x)) + 1)
        .ToList();
}

这会生成副本,而Jon会修改列表。

答案 3 :(得分:0)

我能想到的唯一解决方案是编写一个从列表末尾开始的循环,并搜索一个不是空字符串的元素。不知道任何有用的库函数。一旦你知道了最后一个好的元素,就知道要删除哪些元素。

小心不要在迭代时修改集合。倾向于打破迭代器。

答案 4 :(得分:0)

我总是想提出最通用的解决方案。为什么用列表和字符串限制自己?让我们为通用枚举做一个算法!

public static class EnumerableExtensions
{
    public static IEnumerable<T> TrimEnd<T>(this IEnumerable<T> enumerable, Predicate<T> predicate)
    {
        if (predicate == null)
        {
            throw new ArgumentNullException("predicate");
        }

        var accumulator = new LinkedList<T>();
        foreach (var item in enumerable)
        {
            if (predicate(item))
            {
                accumulator.AddLast(item);
            }
            else
            {
                foreach (var accumulated in accumulator)
                {
                    yield return accumulated;
                }

                accumulator.Clear();

                yield return item;
            }
        }
    }
}

像这样使用:

var list = new[]
{
    "Joe", 
    "", 
    "Bill", 
    "Bill", 
    "", 
    "Scott", 
    "Joe", 
    "", 
    ""
};
foreach (var item in list.TrimEnd(string.IsNullOrEmpty))
{
    Console.WriteLine(item);
}