寻找一个linq解决方案来取代for循环

时间:2014-12-17 22:40:27

标签: c# linq

我一直遇到这样的例子。在这种情况下,我想在一个名为 files 的先前加载的变量中为每个FileInfo对象填充一个带有新行的stringbuilder,当然它包含一堆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));
            }

4 个答案:

答案 0 :(得分:7)

就个人而言,我会放弃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()

的单个来电

答案 1 :(得分:2)

您可以使用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"))));

答案 2 :(得分:0)

我经常会在这里提出问题,我选择了各种各样的建议:

            foreach (var fi in files)
            {
                var extra = (fi == files.First() ? "FIRST" : "NOTFIRST");
                sb.AppendLine(fi.Name + extra);
            }

我不愿意检查stringbuilder的长度,因为我还有其他情况,额外非常需要使用linq函数。

我想我可以轻松完成以下操作(对于我所陈述的例子):

            sb.AppendLine(files.First().Name + " FIRST");
            sb.AppendLine(String.Join(Environment.NewLine,
            files.Skip(1).Select( fi => fi.Name + " NOTFIRST")));

但说实话,它的一半是可读的。

答案 3 :(得分:0)

我并不是说这是最好的方法,但写起来很有趣:

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();