An analog of String.Join(string, string[]) for IEnumerable<T>

强颜欢笑 提交于 2019-12-04 05:06:48

I wrote an extension method:

    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:

tableRowList.Join(()=>new TableRow())

The Linq equivalent of String.Join is Aggregate

For instance:

IEnumerable<string> strings;
string joinedString = strings.Aggregate((total,next) => total + ", " + next);

If given an IE of TableRows, the code will be similar.

In .NET 3.5 you can use this extension method:

public static string Join<TItem>(this IEnumerable<TItem> enumerable, string separator)
{
   return string.Join(separator, enumerable.Select(x => x.ToString()).ToArray());
}

or in .NET 4

public static string Join<TItem>(this IEnumerable<TItem> enumerable, string separator)
{
   return string.Join(separator, enumerable);
}

BUT the question wanted a separator after each element including the last for which this (3.5 version) would work:-

public static string AddDelimiterAfter<TItem>(this IEnumerable<TItem> enumerable, string delimiter)
{
   return string.Join("", enumerable.Select(x => x.ToString() + separator).ToArray());
}

You could also use .Aggregate to do this without an extension method.

Svish

If I couldn't find a method that suits my need, I would just create my own. And extension methods are very nice that way since they let you extend stuff like that. Don't know much about asp:table, but here is an extension method at least which you can tweak to whatever :p

public static class TableRowExtensions
{
    public string JoinRows(this IEnumerable<TableRow> rows, string separator)
    {
        // do what you gotta do
    }
}
Michael Kropat

What you are looking for is an Intersperse function. For LINQ implementations of such a function, see this question.


Incidentally, another possible analog of String.Join is the Intercalate function, which is actually what I was looking for:

public static IEnumerable<T> Intercalate<T>(this IEnumerable<IEnumerable<T>> source,
                                            IEnumerable<T> separator) {
    if (source == null) throw new ArgumentNullException("source");
    if (separator == null) throw new ArgumentNullException("separator");
    return source.Intersperse(separator)
        .Aggregate(Enumerable.Empty<T>(), Enumerable.Concat);
}

I find that I use this extension method a lot.

With luck, it might be incorporated into C#.

public static class Extensions
{
    public static string ToString(this IEnumerable<string> list, string separator)
    {
        string result = string.Join(separator, list);
        return result;
    }
}

Usage:

var people = new[]
{
    new { Firstname = "Bruce", Surname = "Bogtrotter" },
    new { Firstname = "Terry", Surname = "Fields" },
    new { Firstname = "Barry", Surname = "Wordsworth"}
};

var guestList = people
                    .OrderBy(p => p.Firstname)
                    .ThenBy(p => p.Surname)
                    .Select(p => $"{p.Firstname} {p.Surname}")
                    .ToString(Environment.NewLine);

There is no built in method to do that, you should roll your own.

If you are going to do this sort of thing frequently, then it's worth building your own extension method to do it. The implementation below allows you to do the equivalent of string.Join(", ", arrayOfStrings) where the arrayOfStrings can be an IEnumerable<T>, and separator can be any object at all. It allows you to do something like this:

var names = new [] { "Fred", "Barney", "Wilma", "Betty" };
var list = names
    .Where(n => n.Contains("e"))
    .Join(", ");

Two things I like about this are:

  1. It's very readable in a LINQ context.
  2. It's fairly efficient because it uses StringBuilder and avoids evaluating the enumeration twice.
public static string Join<TItem,TSep>(
    this IEnumerable<TItem> enuml,
    TSep                    separator)
{
    if (null == enuml) return string.Empty;

    var sb = new StringBuilder();

    using (var enumr = enuml.GetEnumerator())
    {
        if (null != enumr && enumr.MoveNext())
        {
            sb.Append(enumr.Current);
            while (enumr.MoveNext())
            {
                sb.Append(separator).Append(enumr.Current);
            }
        }
    }

    return sb.ToString();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!