修剪列表的最佳方法是什么
本文关键字:方法 是什么 最佳 列表 修剪 | 更新日期: 2023-09-27 18:21:45
我有一个字符串列表。它在其他地方生成,但我将在下面生成它,以帮助描述这个简化的示例
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))
老实说,我只会在没有任何LINQ的情况下编写它——毕竟,你正在修改一个集合,而不仅仅是查询它:
void TrimList(List<string> list)
{
int lastNonEmpty = list.FindLastIndex(x => !string.IsNullOrEmpty(x));
int firstToRemove = lastNonEmpty + 1;
list.RemoveRange(firstToRemove, list.Count - firstToRemove);
}
如果你真的想创建一个新的列表,那么基于LINQ的解决方案是可以的。。。尽管可能有些低效(因为Reverse
必须缓冲所有内容)。
利用Reverse
和SkipWhile
。
list = list.Reverse().SkipWhile(s => String.IsNullOrEmpty(s)).Reverse().ToList();
List<T>
(不是接口)有一个FindLastIndex
方法。因此,你可以用一种方法来包装它:
static IList<string> TrimList(List<string> input) {
return input.Take(input.FindLastIndex(x => !string.IsNullOrEmpty(x)) + 1)
.ToList();
}
这会生成一个副本,而Jon会修改列表。
我能想到的唯一解决方案是编写一个循环,从列表的末尾开始,搜索一个不是空字符串的元素。不知道有什么库函数会有帮助。一旦你知道了最后一个好元素,你就知道该删除哪些了。
在迭代集合时要小心不要修改它。这会破坏迭代器。
我总是喜欢想出最通用的解决方案。为什么要用列表和字符串来限制自己?让我们为泛型枚举生成一个算法!
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);
}