Finding linq solution to replace loop
I constantly come across such examples. In this case, I want to populate the stringbuilder with a new line for each FileInfo object in a previously loaded variable called files , which of course contains a bunch of FileInfo objects. For the first object, I want to add FIRST after the text, and then for everything else, I want to add NOTFIRST . To do this with forloop, I need to set up a counter, execute an if statement, and increment the counter.
I found out if linq is enough that its at my fingertip, but I know there must be an elegant LINQ solution.
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));
}
source to share
You can use the Select overload that gives the current index: http://msdn.microsoft.com/pl-pl/library/bb534869(v=vs.110).aspx
I also don't like the mutating state when using linq, so I would use String.Join instead.
mysb.AppendLine(String.Join(Environment.NewLine,
files.Select((fi, i) => String.Format(fi.Name, i == 0 ? "FIRST" : "NOTFIRST"))));
source to share
Personally, I would ditch LINQ and stick with what you have, it's just simpler:
var mysb = new StringBuilder();
foreach (FileInfo fi in files)
{
string extra = mysb.Length == 0 ? "FIRST" : "NOTFIRST";
mysb.Append(fi.Name);
mysb.AppendLine(extra);
}
(It's not clear to me why you are treating the filename as a valid format string ... of course, if it is indeed a valid format string, you can change my two calls to Append()
and AppendLine()
back to a single call with string.Format()
)
source to share
As often happens, I ask questions here, I went with a hybrid of sentences:
foreach (var fi in files)
{
var extra = (fi == files.First() ? "FIRST" : "NOTFIRST");
sb.AppendLine(fi.Name + extra);
}
I didn't want to check the length of the stringbuilder because I have other scenarios where extra quite often requires using the linq function.
I suppose I could just as easily do the following (for my stated example):
sb.AppendLine(files.First().Name + " FIRST");
sb.AppendLine(String.Join(Environment.NewLine,
files.Skip(1).Select( fi => fi.Name + " NOTFIRST")));
But to be honest, half of it is readable.
source to share
I am not suggesting that this is the best way to do it, but it was fun to write:
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();
source to share