鉴于List<string>
我需要删除列表开头和结尾的所有空行。
注意:我认为空行是没有内容的行,但可能包含空格和制表符。这是检查行是否为空的方法:
private bool HasContent(string line)
{
if (string.IsNullOrEmpty(line))
return false;
foreach (char c in line)
{
if (c != ' ' && c != '\t')
return true;
}
return false;
}
您建议使用哪些有效且可读的代码?
[" ", " ", " ", " ", "A", "B", " ", "C", " ", "D", " ", " ", " "]
应该修剪这样的列表,方法是删除开头的所有空行和结束以下结果:
["A", "B", " ", "C", " ", "D"]
答案 0 :(得分:8)
var results = textLines1.SkipWhile(e => !HasContent(e))
.Reverse()
.SkipWhile(e => !HasContent(e))
.Reverse()
.ToList();
它是如何工作的?从列表中跳过所有空行,反转它并执行相同操作(实际上跳过列表后面的所有空行)。经过另一次逆转后,你会得到正确的结果。
如果列表非常庞大,您可以考虑使用标准while
循环并列出索引,因为性能方面的考虑因素,但对于正常数据,传递回归应该不重要。
答案 1 :(得分:4)
首先,有一个内置方法可以检查:String.IsNullOrWhitespace();
ColinE提供的答案不符合要求,因为它删除了所有空行,而不仅仅是在开头或结尾。
我认为你需要建立自己的解决方案:
int start = 0, end = sourceList.Count - 1;
while (start < end && String.IsNullOrWhitespace(sourceList[start])) start++;
while (end >= start && String.IsNullOrWhitespace(sourceList[end])) end--;
return sourceList.Skip(start).Take(end - start + 1);
答案 2 :(得分:2)
使用Linq,您可以执行以下操作:
IEnumerable<string> list = sourceList.SkipWhile(source => !HasContent(source))
.TakeWhile(source => HasContent(source));
这&#39;跳过&#39;字符串,直到找到一个有内容的字符串,然后&#39;采取&#39;所有字符串,直到找到没有内容的字符串。
虽然@MarcinJuraszek指出,这将在没有内容的第一行之后停止,而不是删除列表末尾的那些。
为此,您可以使用以下内容:
IEnumerable<string> list = sourceList.SkipWhile(source => !HasContent(source))
.Reverse()
.SkipWhile(source => !HasContent(source))
.Reverse();
有点令人费解,但应该这样做。
答案 3 :(得分:2)
检查我刚才做的扩展方法:
public static class ListExtensions
{
public static List<string> TrimList(this List<string> list)
{
int listCount = list.Count;
List<string> listCopy = list.ToList();
List<string> result = list.ToList();
// This will encapsulate removing an item and the condition to remove it.
// If it removes the whole item at some index, it return TRUE.
Func<int, bool> RemoveItemAt = index =>
{
bool removed = false;
if (string.IsNullOrEmpty(listCopy[index]) || string.IsNullOrWhiteSpace(listCopy[index]))
{
result.Remove(result.First(item => item == listCopy[index]));
removed = true;
}
return removed;
};
// This will encapsulate the iteration over the list and the search of
// empty strings in the given list
Action RemoveWhiteSpaceItems = () =>
{
int listIndex = 0;
while (listIndex < listCount && RemoveItemAt(listIndex))
{
listIndex++;
}
};
// Removing the empty lines at the beginning of the list
RemoveWhiteSpaceItems();
// Now reversing the list in order to remove the
// empty lines at the end of the given list
listCopy.Reverse();
result.Reverse();
// Removing the empty lines at the end of the list
RemoveWhiteSpaceItems();
// Reversing again in order to recover the right list order.
result.Reverse();
return result;
}
}
......及其用法:
List<string> list = new List<string> { "\t", " ", " ", "a", "b", "\t", " ", " " };
// The TrimList() extension method will return a new list without
// the empty items at the beginning and the end of the sample list!
List<string> trimmedList = list.TrimList();
答案 4 :(得分:2)
此方法修改原始 List<string>
,而不是使用所需属性创建新对象:
static void TrimEmptyLines(List<string> listToModify)
{
if (listToModify == null)
throw new ArgumentNullException();
int last = listToModify.FindLastIndex(HasContent);
if (last == -1)
{
// no lines have content
listToModify.Clear();
return;
}
int count = listToModify.Count - last - 1;
if (count > 0)
listToModify.RemoveRange(last + 1, count);
int first = listToModify.FindIndex(HasContent);
if (first > 0)
listToModify.RemoveRange(0, first);
}
在此代码中,HasContent
是原始问题的方法。对于委托,可以使用像lambda这样的匿名函数。
答案 5 :(得分:1)
以下代码可满足您的需求:
List<string> lines = new List<string> {" \n\t", " ", "aaa", " \t\n", "bb", "\n", " "};
IEnumerable<string> filtered = lines.SkipWhile(String.IsNullOrWhiteSpace).Reverse().SkipWhile(String.IsNullOrWhiteSpace).Reverse();
它将列表反转两次,因此如果性能是关键,它可能不是理想的解决方案。
答案 6 :(得分:-1)
您可以使用isnullorwhitespace进行检查:请参阅下面的示例。
List<string> lines = new List<string>();
lines.Add(" ");
lines.Add("one");
lines.Add("two");
lines.Add("");
lines.Add("");
lines.Add("five");
lines.Add("");
lines.Add(" ");
lines.RemoveAll(string.IsNullOrWhiteSpace);
答案 7 :(得分:-1)
List<string> name = new List<string>();
name.Add(" ");
name.Add("rajesh");
name.Add("raj");
name.Add("rakesh");
name.Add(" ");
for (int i = 0; i < name.Count(); i++)
{
if (string.IsNullOrWhiteSpace(Convert.ToString(name[i])))
{
name.RemoveAt(i);
}
}
答案 8 :(得分:-2)
关于构建代码,我猜您的行既不包含空格也不包含制表符,因此您可以将foreach
替换为
if(line.Contains(' ') || line.Contains('\t'))
return false;
return true;
答案 9 :(得分:-2)
List<string> name = new List<string>();
name.Add(" ");
name.Add("rajesh");
name.Add("raj");
name.Add("rakesh");
name.Add(" ");
name.RemoveAt(0);
name.RemoveAt(name.Count() - 1);