C# 修剪列表的最佳方法是什么?
我有一个字符串列表。它是在别处生成的,但我将在下面生成它来帮助描述这个简化的示例C# 修剪列表的最佳方法是什么?,c#,linq,collections,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); 我想
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);
我想要一个修剪这个列表的函数,通过修剪,我想删除数组末尾的所有空白字符串项,在本例中是最后两个
注释:我仍然希望保留数组中的第二个项目或其他不在末尾的空白项目,因此我不能做.Woeer-= > String。 利用倒车和滑行的优势
老实说,我只想在没有任何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必须缓冲所有内容。老实说,我只想在没有任何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必须缓冲所有内容。我能想到的唯一解决方案是编写一个从列表末尾开始的循环,并搜索不是空字符串的元素。我不知道有什么库函数会有帮助。一旦知道了最后一个好元素,就知道要删除哪些元素
在对集合进行迭代时,请注意不要修改集合。倾向于破坏迭代器。我能想到的唯一解决方案是编写一个从列表末尾开始的循环,并搜索不是空字符串的元素。我不知道有什么库函数会有帮助。一旦知道了最后一个好元素,就知道要删除哪些元素 在对集合进行迭代时,请注意不要修改集合。倾向于中断迭代器。列表没有接口具有FindLastIndex方法。因此,您可以将其包装在一个方法中:
static IList<string> TrimList(List<string> input) {
return input.Take(input.FindLastIndex(x => !string.IsNullOrEmpty(x)) + 1)
.ToList();
}
这将生成一个副本,而Jon的将修改列表。列表没有接口具有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;
}
}
}
}
我总是喜欢想出最通用的解决方案。为什么要用列表和字符串来限制自己?让我们为泛型枚举创建一个算法
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;
}
}
}
}
@是的,那是一个错误-有一种更简洁的方法可以找到最后一个索引。看我的编辑:哦,你编辑了它。。我想说,根据我的回答,具体清单有找到索引的方法。。但你已经编辑过了。所以还是+1!:@AlexD:不是在我编辑之后-它会找到字符串不为null或空的最后一个索引。不过,我一开始确实是倒过来的。我的电话里有个窃听器。还有我的情况。基本上完全失败了。我想现在没事了:@AlexD:当然。如果你发现了什么,一定要说@是的。。。一个错误导致另一个错误。甚至可能根本不需要这个条件。。。测试。@AlexD:是的,那是一个bug——有一种更简洁的方法可以找到最后一个索引。看我的编辑:哦,你编辑了它。。我想说,根据我的回答,具体清单有找到索引的方法。。但你已经编辑过了。所以还是+1!:@AlexD:不是在我编辑之后-它会找到字符串不为null或空的最后一个索引。不过,我一开始确实是倒过来的。我的电话里有个窃听器。还有我的情况。基本上完全失败了。我想现在没事了:@AlexD:当然。如果你发现了什么,一定要说@是的。。。一个错误导致另一个错误。甚至可能根本不需要这个条件。。。正在测试。@user2864740是的,他正在分配给一个列表。接得好@用户2864740是的,他正在分配一个列表。接得好!