附加/连接两个IEnumerable序列
我有两套datarows。 它们每个都是IEnumerable。 我想追加/连接这两个列表成一个列表。 我相信这是可行的。 我不想做一个for循环,并注意到两个列表中有一个联合方法和一个联接方法。 有任何想法吗?
假设你的对象是相同types的,你可以使用Union
或者Concat
。 请注意,与SQL UNION
关键字一样, Union
操作将确保重复项被删除,而Concat
(如UNION ALL
)将简单地将第二个列表添加到第一个列表的末尾。
IEnumerable<T> first = ...; IEnumerable<T> second = ...; IEnumerable<T> combined = first.Concat(second);
要么
IEnumerable<T> combined = first.Union(second);
如果他们是不同types的,那么你将不得不Select
他们共同的东西。 例如:
IEnumerable<TOne> first = ...; IEnumerable<TTwo> second = ...; IEnumerable<T> combined = first.Select(f => ConvertToT(f)).Concat( second.Select(s => ConvertToT(s)));
其中ConvertToT(TOne f)
和ConvertToT(TTwo s)
表示以某种方式将TOne
(和TTwo
)的实例转换为T
的实例的操作。
我刚刚遇到类似的情况,我需要连接多个序列。
自然search谷歌/ StackOverflow现有的解决scheme,但没有发现任何东西没有评估枚举,例如转换为数组,然后使用Array.Copy()
等,所以我写了一个名为ConcatMultiple的扩展和静态实用方法。
希望这可以帮助任何需要这样做的人。
/// <summary> /// Concatenates multiple sequences /// </summary> /// <typeparam name="TSource">The type of the elements of the input sequences.</typeparam> /// <param name="first">The first sequence to concatenate.</param> /// <param name="source">The other sequences to concatenate.</param> /// <returns></returns> public static IEnumerable<TSource> ConcatMultiple<TSource>(this IEnumerable<TSource> first, params IEnumerable<TSource>[] source) { if (first == null) throw new ArgumentNullException("first"); if (source.Any(x => (x == null))) throw new ArgumentNullException("source"); return ConcatIterator<TSource>(source); } private static IEnumerable<TSource> ConcatIterator<TSource>(IEnumerable<TSource> first, params IEnumerable<TSource>[] source) { foreach (var iteratorVariable in first) yield return iteratorVariable; foreach (var enumerable in source) { foreach (var iteratorVariable in enumerable) yield return iteratorVariable; } } /// <summary> /// Concatenates multiple sequences /// </summary> /// <typeparam name="TSource">The type of the elements of the input sequences.</typeparam> /// <param name="source">The sequences to concatenate.</param> /// <returns></returns> public static IEnumerable<TSource> ConcatMultiple<TSource>(params IEnumerable<TSource>[] source) { if (source.Any(x => (x == null))) throw new ArgumentNullException("source"); return ConcatIterator<TSource>(source); } private static IEnumerable<TSource> ConcatIterator<TSource>(params IEnumerable<TSource>[] source) { foreach (var enumerable in source) { foreach (var iteratorVariable in enumerable) yield return iteratorVariable; } }
Join方法就像一个SQL连接,其中列表根据条件进行交叉引用,它不是string连接或添加到列表。 Union方法不像Concat方法那样做你想做的事情,但都是LAZY评估,并且要求参数是非空的。 他们返回一个ConcatIterator或一个UnionIterator, 如果重复调用这可能会导致问题 。 热切的评估结果会导致不同的行为,如果这是你想要的,那么可以使用像下面这样的扩展方法。
public static IEnumerable<T> myEagerConcat<T>(this IEnumerable<T> first, IEnumerable<T> second) { return (first ?? Enumerable.Empty<T>()).Concat( (second ?? Enumerable.Empty<T>())).ToList(); }