How to Concatenate Two Ienumerable<T> into a New Ienumerable<T>

How to concatenate two IEnumerableT into a new IEnumerableT?

Yes, LINQ to Objects supports this with Enumerable.Concat:

var together = first.Concat(second);

NB: Should first or second be null you would receive a ArgumentNullException. To avoid this & treat nulls as you would an empty set, use the null coalescing operator like so:

var together = (first ?? Enumerable.Empty<string>()).Concat(second ?? Enumerable.Empty<string>()); //amending `<string>` to the appropriate type

Concatenate multiple IEnumerableT

Use SelectMany:

public static IEnumerable<T> Concatenate<T>(params IEnumerable<T>[] lists)
{
return lists.SelectMany(x => x);
}

Merge two IEnumerables in elegant way

Just check for null and assign Enumerable.Empty if it is null. This can be done in one step with the null coalescing operator ??

var ienumerable1 = GetEnumerable1() ?? Enumerable.Empty<WhateverType>();
var ienumerable2 = GetEnumerable2() ?? Enumerable.Empty<WhateverType>();

return ienumerable1.Union(ienumerable2);

Merge two IEnumerable with LINQ

You can use GroupBy combined with selecting maximum in group via Aggregate:

IEnumerable<Application> final = applications1
.Concat(applications2)
.GroupBy(a => a.Id)
.Select(g => g.Aggregate((acc, curr) => acc.Version > curr.Version ? acc: curr))
.ToList();

Appending/concatenating two IEnumerable sequences

Assuming your objects are of the same type, you can use either Union or Concat. Note that, like the SQL UNION keyword, the Union operation will ensure that duplicates are eliminated, whereas Concat (like UNION ALL) will simply add the second list to the end of the first.

IEnumerable<T> first = ...;
IEnumerable<T> second = ...;

IEnumerable<T> combined = first.Concat(second);

or

IEnumerable<T> combined = first.Union(second);

If they are of different types, then you'll have to Select them into something common. For example:

IEnumerable<TOne> first = ...;
IEnumerable<TTwo> second = ...;

IEnumerable<T> combined = first.Select(f => ConvertToT(f)).Concat(
second.Select(s => ConvertToT(s)));

Where ConvertToT(TOne f) and ConvertToT(TTwo s) represent an operation that somehow converts an instance of TOne (and TTwo, respectively) into an instance of T.

Concat two Ienumerables of different types

You cannot combine two sequences of different types in one sequence, unless you project some of their properties in a common type and create a sequence of this type.

For instance, let we have the two following classes:

public class A
{
public int ID { get; set; }
public string FirstName { get; set; }
public int Age { get; set; }
}

and

public class B
{
public int ID { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public bool Sex { get; set; }
}

Furthermore, let that you have two sequences, one containing objects of type classA and the other containing objects of type classB. Then, if you declare a third type called classCommon, that would contain the commont properties of classA and classB,

public class classCommon
{
public int ID { get; set; }
public int Age { get; set; }
}

you could try the following:

var result = listA.Select(x => new classCommon { ID = x.ID, Age = x.Age })
.Concat(listB.Select(x => new classCommon{ ID = x.ID, Age = x.Age });

Merging two IEnumerableTs

Try this.

public static IEnumerable<Person> SmartCombine(IEnumerable<Person> fallback, IEnumerable<Person> translated) {
return translated.Concat(fallback.Where(p => !translated.Any(x => x.id.equals(p.id)));
}

How to concatenate two IEnumerable's and project them into a grouping

You can do Concat/Union, and then group by Date. Code will look approximately like this:

var list3 = List1.Concat(List2)
.GroupBy(x => x.Date)
.Select(grouping =>
new StatusGroup
{
Date = grouping.Key,
SuccessCount = grouping.Sum(x => x.SuccessCount),
FailCount = grouping.Sum(x => x.FailCount)
});

Concatenate two infinite C# IEnumerables together in no particular order

This is fairly easily achieved with System.Reactive

static void Main()
{
get1().ToObservable(TaskPoolScheduler.Default).Subscribe(Print);
get2().ToObservable(TaskPoolScheduler.Default).Subscribe(Print);
}

static void Print(int i)
{
Console.WriteLine(i);
}

static IEnumerable<int> get1()
{
while (true)
{
System.Threading.Thread.Sleep(1000);
yield return 1;
}
}

static IEnumerable<int> get2()
{
while (true)
{
System.Threading.Thread.Sleep(200);
yield return 2;
}
}

This produces the following output on my machine:

2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 1 ...

Note that ToObservable is called with the argument TaskPoolScheduler.Default; just calling ToObservable without it will result in synchronous execution, meaning it will keep enumerating the first sequence forever and never get to the second one.



Related Topics



Leave a reply



Submit