The problem:
Write me a function that takes a non-null IEnumerable
(1) If the sequence is empty then the resulting string is "{}".
(2) If the sequence is a single item "ABC" then the resulting string is "{ABC}".
(3) If the sequence is the two item sequence "ABC", "DEF" then the resulting string is "{ABC and DEF}".
(4) If the sequence has more than two items, say, "ABC", "DEF", "G", "H" then the resulting string is "{ABC, DEF, G and H}". (Note: no Oxford comma!)
My solution:
static string JoinStrings(IEnumerable<string> strings) {
int len = strings.Count();
return "{"+(
(len > 1) ?
strings.Take(len - 1)
.Aggregate((string head, string tail) => head+", "+tail)+
" and " +strings.Last()
: (len == 1) ?
strings.First()
: "")+
"}";
}
2 comments:
I find the double use of the ternary operator makes the code more unreadable than it need be.
You basically have:
return "{" + (len>1 ? a : len==1 ? b : c) + "}";
For clarity I would go for:
string inside;
if (len > 1)
inside = a;
else if (len == 1)
inside = b;
return "{" + inside + "}";
Note that you can get rid of the result I labelled c from the original double ternary because it just creates "" which inside will default to.
Looking at some of the answers on Eric's blog I'm amazed at how complicated they have managed to make it. If they're doing it for efficiency reasons it seems to be a huge case of premature optimisation (There was no performance requirement in the spec).
I just reformatted the code to make it look more like what you proposed, except for the "if". you're right, the code is not readable, but my particular challenge was to make it as short as possible.
And I looked at the solutions people came up with and... wow!, I guess people went for additional challenges like I did (faster, smaller, uglier, etc)
Post a Comment