Use Linq to Collaps Multiply Collections into One Collection

Elegant way to combine multiple collections of elements?

I think you might be looking for LINQ's .Concat()?

var combined = foo.Concat(bar).Concat(foobar).Concat(...);

Alternatively, .Union() will remove duplicate elements.

C# Join multiple collections into one

If you have multiple variables containing List<MeasuredData>, one for each sensor, you can group them in an array and then query them.

First, you need an extension method to round the DateTimes per @jdweng if you aren't already canonicalizing them as you acquire them.

public static DateTime Round(this DateTime dt, TimeSpan rnd) {
if (rnd == TimeSpan.Zero)
return dt;
else {
var ansTicks = dt.Ticks + Math.Sign(dt.Ticks) * rnd.Ticks / 2;
return new DateTime(ansTicks - ansTicks % rnd.Ticks);
}
}

Now you can create an array of the sensor reading Lists:

var sensorData = new[] { sensor0, sensor1, sensor2, sensor3 };

Then you can extract all the rounded times to create the left hand side of the table:

var roundTo = TimeSpan.FromSeconds(1);
var times = sensorData.SelectMany(sdl => sdl.Select(md => md.Time.Round(roundTo)))
.Distinct()
.Select(t => new { Time = t, Measurements = Enumerable.Empty<MeasuredData>() });

Then you can join each sensor to the table:

foreach (var oneSensorData in sensorData)
times = times.GroupJoin(oneSensorData, t => t.Time, md => md.Time.Round(roundTo),
(t, mdj) => new { t.Time, Measurements = t.Measurements.Concat(mdj) });

Finally, you can convert each row to the time and a List of measurements ordered by time:

var ans = times.Select(tm => new { tm.Time, Measurements = tm.Measurements.ToList() })
.OrderBy(tm => tm.Time);

If you wanted to flatten the List of measurements out to fields in the answer, you would need to do that manually with another Select.

How to merge a collection of collections in Linq

Try

var it = GetTheNestedCase();
return it.SelectMany(x => x);

SelectMany is a LINQ transformation which essentially says "For Each Item in a collection return the elements of a collection". It will turn one element into many (hence SelectMany). It's great for breaking down collections of collections into a flat list.

How to use LINQ to combine two or more collections into one collection

You can use Linq Union. I've faked up the initialization since your example doesn't really have collections, but still retain the anonymous nature of the elements since I think this is what you're intending.

static void Main(string[] args) {
var dummys = new List<int>(); dummys.Add(1);
var col1 = from dummy in dummys
select new { Name1 = "Frank", ID1 = 123, ABC = "abc" };
var col2 = from dummy in dummys
select new { Name2 = "Harry", ID2 = 456, XYZ = "xyz" };
var col3 = from dummy in dummys
select new { Name3 = "Bob" };

var col4 = col1.Select(c=> new { FirstName=c.Name1, Ident=new Nullable<int>(c.ID1)})
.Union(col2.Select(c=> new { FirstName=c.Name2, Ident=new Nullable<int>(c.ID2)}))
.Union(col3.Select(c=> new { FirstName=c.Name3, Ident=new Nullable<int>()}));

foreach (var c in col4) {
Console.WriteLine(c);
}
Console.ReadKey();
}

How to merge 2 Collections from different types into one custom type on LINQ C#?

You can perform the equivalent of a cross join in LINQ like this:

var regionConcepts = regions.SelectMany(x => concepts.Select(y => new { Region = x.Name, Concept = y.Name }));


Related Topics



Leave a reply



Submit