Join List<string> Together with Commas Plus "and" for Last Element
You could do this
string finalString = String.Join(", ", myList.ToArray(), 0, myList.Count - 1) + ", and " + myList.LastOrDefault();
Here is a solution which works with empty lists and list with a single item in them:
C#
return list.Count() > 1 ? string.Join(", ", list.Take(list.Count() - 1)) + " and " + list.Last() : list.FirstOrDefault();
VB
Return If(list.Count() > 1, String.Join(", ", list.Take(list.Count() - 1)) + " and " + list.Last(), list.FirstOrDefault())
I use the following extension method (with some code guarding too):
public static string OxbridgeAnd(this IEnumerable<String> collection)
{
var output = String.Empty;
var list = collection.ToList();
if (list.Count > 1)
{
var delimited = String.Join(", ", list.Take(list.Count - 1));
output = String.Concat(delimited, ", and ", list.LastOrDefault());
}
return output;
}
Here is a unit test for it:
[TestClass]
public class GrammarTest
{
[TestMethod]
public void TestThatResultContainsAnAnd()
{
var test = new List<String> { "Manchester", "Chester", "Bolton" };
var oxbridgeAnd = test.OxbridgeAnd();
Assert.IsTrue( oxbridgeAnd.Contains(", and"));
}
}
EDIT
This code now handles null and a single element:
public static string OxbridgeAnd(this IEnumerable<string> collection)
{
var output = string.Empty;
if (collection == null) return null;
var list = collection.ToList();
if (!list.Any()) return output;
if (list.Count == 1) return list.First();
var delimited = string.Join(", ", list.Take(list.Count - 1));
output = string.Concat(delimited, ", and ", list.LastOrDefault());
return output;
}