我有一个字符串列表。它是在其他地方生成的,但我将在下面生成它以帮助描述这个简化的例子
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))
答案 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)
利用Reverse
和SkipWhile
。
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);
}