C# 如何修剪列表<;字符串>;那么前面和后面的空行都被删除了吗?

C# 如何修剪列表<;字符串>;那么前面和后面的空行都被删除了吗?,c#,generics,string,trim,C#,Generics,String,Trim,最简单的方法是什么? 结果应该是: 1: one 2: two 3: 4: 5: five 代码: 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; 命名空间TestLines8833 { 班级计划 { 静态void Main(字符串[]参数) { 列表行=新列表(); 行。添加(“”); 行。添加(“一”); 行。添加(“两行”); 行。添加(“”); 行。添加(“”); 行。添加(“五”); 行。添加(“”); 行。添加

最简单的方法是什么?

结果应该是:

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

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
命名空间TestLines8833
{
班级计划
{
静态void Main(字符串[]参数)
{
列表行=新列表();
行。添加(“”);
行。添加(“一”);
行。添加(“两行”);
行。添加(“”);
行。添加(“”);
行。添加(“五”);
行。添加(“”);
行。添加(“”);
line.TrimList();
}
}
公共静态类助手
{
公共静态列表(此列表)
{
//???
}
}
}

如果要删除空字符串,可以执行以下操作

lines = lines.Where(s => ! string.IsNullOrEmpty(s)).ToList();
更新:很抱歉刚才看到您的编辑,您希望保留内部空白


在这种情况下,我只想使用一种扩展方法,就像您上面提到的那样,因为我认为没有更简单的方法来实现它。

好的,现在我了解了所需的结果:

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);
    }
}
公共静态类帮助程序
{
//如果需要,请调整此项以使用修剪、避免为空等
私有静态只读谓词
NonBlankLinePredicate=x=>x.Length!=0;
公共静态列表(此列表)
{
int start=list.FindIndex(非blanklinepredicate);
int end=list.findlastinex(非blanklinepredicate);
//起点和终点都是-1,或者两者都不是
如果(开始==-1)
{
返回新列表();
}
返回列表.GetRange(开始,结束-开始+1);
}
}
请注意,这不会更改现有列表-它会返回一个包含所需内容的新列表。考虑到您已经为该方法指定了一个返回类型,我们还不清楚您想要什么行为,但是您的示例在不使用结果的情况下调用了它。就我个人而言,我更喜欢无副作用的方法,尽管可能值得更改名称:)

这是怎么回事:

    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);
        }
    }
publicstaticvoidtrimlist(此列表){
而(0!=list.Count&&string.IsNullOrEmpty(list[0])){
移除列表(0);
}
而(0!=list.Count&&string.IsNullOrEmpty(list[list.Count-1])){
list.RemoveAt(list.Count-1);
}
}

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

没有任何内置功能来执行类似的特定操作。您可以从头到尾检查项目,并删除空字符串。为了尽量减少列表上的操作(重复使用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);
}
publicstaticvoidtrimlist(此列表){
int-cnt=0;
而(cnt0)列表,则移除范围为(0,cnt);
cnt=0;
而(cnt0)list.RemoveRange(list.Count-cnt,cnt);
}
试试这个:

public static List<string> TrimList(this List<string> list)  
    {  
        return list.SkipWhile(l => String.IsNullOrEmpty(l)).Reverse().SkipWhile(l => String.IsNullOrEmpty(l)).Reverse();
    } 
公共静态列表TrimList(此列表)
{  
return list.SkipWhile(l=>String.IsNullOrEmpty(l)).Reverse().SkipWhile(l=>String.IsNullOrEmpty(l)).Reverse();
} 

有时,从可读性和性能角度来看,好的旧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;
        }
    }
}
公共静态列表TrimList(此列表)
{
TrimListStart();
vat l=list.Reverse().ToList();
l、 TrimListStart();
返回l;
}
public void TrimListStart(此列表)
{
foreach(新列表中的var s(列表))
{
if(string.string.IsNullOrWhiteSpace)
{
列表。删除;
}
其他的
{
打破
}
}
}
intstart=stringList.FindIndex((i=>i.Trim()!=);
int end=stringList.findlastinex((i=>i.Trim()!=);
列表范围=新列表();
如果(开始!=-1&&end!=-1)
range=stringList.GetRange(start,(end-start+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();
    }
}

使用string.IsNullOrEmpty比检查字符串长度更安全我不是想教我祖母吃蛋,但是。奶奶在这里挖个小洞然后@二元担忧者:是的,你可以。这取决于-包含空引用的列表是否表示bug(在这种情况下,异常是合适的)?我怀疑爱德华很乐意自己解决这个问题——不过我会编辑一下,让它更清楚@jk:我在一段时间前修复了这个问题:)这是真的,我们的API被许多不同的客户端应用程序调用,有时我们得到空字符串,有时我们得到空字符串。如果string.IsNullOrEmpty不是由框架提供的,我们将推出自己的:)这很简单,但效率低下。此外,如果列表只有空字符串,它会抛出IndexOutOfRangeException。单击-为什么“0!=list.Count”而不是“list.Count!=0”?我们没有使用C/C++:)@Jon Skeet:谢谢你的评论,但是已经太晚了,“0!=”在我的手指上是硬连接的:)现在它没有抛出异常,但仍然效率低下……;)无论从性能还是可读性方面,我都不能说我喜欢这一点。我同意LINQ不一定是这里的答案,但使用FindIndex、FindLastIndex和GetRange(根据我和Carra的答案)对我来说更易读、更简单。。。
    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));
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));