Possible Duplicate:
Extension method for Enumerable.Intersperse?
I have a List<string>
like this:
"foo", "bar", "cat"
I want it to look like this:
"foo", "-", "bar", "-", "cat"
Is there a C# method that does that?
Possible Duplicate:
Extension method for Enumerable.Intersperse?
I have a List<string>
like this:
"foo", "bar", "cat"
I want it to look like this:
"foo", "-", "bar", "-", "cat"
Is there a C# method that does that?
You can make an extension that returns an IEnumerable<T>
with interspersed items:
public static class ListExtensions {
public static IEnumerable<T> Intersperse<T>(this IEnumerable<T> items, T separator) {
bool first = true;
foreach (T item in items) {
if (first) {
first = false;
} else {
yield return separator;
}
yield return item;
}
}
}
The advantage of this is that you don't have to clutter your list with the extra items, you can just use it as it is returned:
List<string> words = new List<string>() { "foo", "bar", "cat" };
foreach (string s in words.Intersperse("-")) {
Console.WriteLine(s);
}
You can of course get the result as a list if you need that:
words = words.Intersperse("-").ToList();
Yes, its a custom method you would write:
List<string> AddDashesToList(List<string> list)
{
if(list.Count > 1)
{
var newList = new List<string>();
foreach(item in list)
{
newList.Add(item);
newList.Add("-");
}
newList.RemoveAt(newList.Count-1);
return newList;
}
else
{
return list;
}
}
public List<string> GetNewList(List<string> list, string s)
{
var result = new List<string>();
foreach (var l in list)
{
result.Add(l);
result.Add(s);
}
result.RemoveAt(result.Count - 1);
return result;
}
you can use this method to get you list
var result = GetNewList(str,"-");
Hah! I've just written something for just this purpose!
public static IEnumerable<T> Interleave<T>(params IEnumerable<T>[] arrays)
{
var enumerators = arrays.Select(array => array.GetEnumerator()).ToArray();
var finished = true;
do
{
finished = true;
foreach (var enumerator in enumerators)
{
if (enumerator.MoveNext())
{
yield return enumerator.Current;
finished = false;
}
}
} while (finished == false);
}
This will interleave the specified enumerables in the order you choose. Then you just fill an enumerable with dashes and interleave that with the original array. It can do more complex things as well.
A while ago I wrote an extension method for this kind of thing:
public static IEnumerable<T>
Join<T>(this IEnumerable<T> src, Func<T> separatorFactory)
{
var srcArr = src.ToArray();
for (int i = 0; i < srcArr.Length; i++)
{
yield return srcArr[i];
if(i<srcArr.Length-1)
{
yield return separatorFactory();
}
}
}
You can use it as follows:
myList.Join(() => "-").ToList()
EDIT:
As pointed out, my previous code results to a string not an array of strings. So here's my edited code:
var list = new List<string> { "foo", "bar", "cat" };
var result = string.Join("-", list.Select(x => x.ToString()).ToArray());
string pattern = "(-)";
string[] test = Regex.Split(result, pattern);
foreach(var str in test)
Console.WriteLine(str);
Retained old code for comparison purposes:
var list = new List<string> { "foo", "bar", "cat" };
var result = string.Join("-", list.Select(x => x.ToString()).ToArray());
Console.WriteLine(result); // prints "foo-bar-cat
Refer to this post. Cheers!