寻找一个 linq 解决方案来取代 for 循环
本文关键字:解决方案 取代 for 循环 linq 一个 寻找 | 更新日期: 2023-09-27 18:34:36
我经常遇到这样的例子。 在这种情况下,我想在以前加载的名为 files 的变量中的每个 FileInfo 对象填充一个字符串生成器,该变量当然包含一堆 FileInfo 对象。 对于第一个对象,我想在文本后添加 FIRST,然后对于其他所有我想添加 NOTFIRST。 要使用 forloop 执行此操作,我必须设置一个计数器,执行 if 语句并增加计数器。
我已经学到了足够多的 linq,它在我的指尖上,但我知道必须有一个优雅的 LINQ 解决方案。
var mysb = new StringBuilder();
var count = 0;
string extra;
foreach (System.IO.FileInfo fi in files)
{
var newLine = fi.Name;
if (count == 0)
extra = "FIRST";
else
extra= "NOTFIRST";
count = count++;
mysb.AppendLine(string.Format("({0} {1})", newLine, extra));
}
就个人而言,我会放弃 LINQ 并坚持使用您拥有的内容,只是更简单:
var mysb = new StringBuilder();
foreach (FileInfo fi in files)
{
string extra = mysb.Length == 0 ? "FIRST" : "NOTFIRST";
mysb.Append(fi.Name);
mysb.AppendLine(extra);
}
(我不清楚为什么您将文件名视为有效的格式字符串......当然,如果它确实是一个有效的格式字符串,你可以将我的两次调用更改为Append()
,AppendLine()
改回带有string.Format()
的单次调用(
您可以使用 Select 的重载来提供当前索引:http://msdn.microsoft.com/pl-pl/library/bb534869(v=vs.110(.aspx
我也不喜欢在使用linq时改变状态,所以我会使用String.Join代替。
mysb.AppendLine(String.Join(Environment.NewLine,
files.Select((fi, i) => String.Format(fi.Name, i == 0 ? "FIRST" : "NOTFIRST"))));
我
经常在这里问问题,我带着混合的疑问:
foreach (var fi in files)
{
var extra = (fi == files.First() ? "FIRST" : "NOTFIRST");
sb.AppendLine(fi.Name + extra);
}
我不愿意检查字符串生成器的长度,因为我还有其他场景,其中额外的几乎需要使用 linq 函数。
我想我可以很容易地完成以下操作(对于我陈述的示例(:
sb.AppendLine(files.First().Name + " FIRST");
sb.AppendLine(String.Join(Environment.NewLine,
files.Skip(1).Select( fi => fi.Name + " NOTFIRST")));
但说实话,它的可读性只有一半。
我并不是说这是最好的方法,但写起来很有趣:
var fi = new [] { new { Name= "A"},
new { Name= "B"},
new { Name= "C"}};
String.Join(Environment.NewLine,
fi.Take(1).Select (f => Tuple.Create(f.Name,"FIRST"))
.Concat(fi.Skip(1).Select (f => Tuple.Create(f.Name,"NONFIRST")))
.Select(t=> String.Format("({0} {1})", t.Item1, t.Item2)))
.Dump();