Reputation: 41
I used linq to create a list of IO_EQUATIONS. An IO_EQUATION consists of a single OUTPUT_POINT and a List of INPUT_POINT. INPUT_POINT and OUTPUT_POINT have a common x, y, and z coordinate but they contain other fields that are not common. I want to flatten out the List of IO_EQUATIONS to either an anonymous type or a specific point type (x, y, and z only) so that I see the Output followed by all the inputs for each IO_EQUATION in a list.
I was able to use linq to list all the OUTPUT_POINTS using the following code. list41 is the list of IO_EQUATIONS
var flat = (from d2 in list41
select (new BINARY_IO()
{
propX = d2.propOutputPoint.propX,
propY = d2.propOutputPoint.propY,
propZ = d2.propOutputPoint.propZ,
propDir = POINT_DIRECTION_Types.Output,
})).ToList();
I was able to use linq to list all the INPUT_POINTS using the following code. list41 is the list of IO_EQUATIONS. propIOPointList is my list of INPUT_POINT
var flat = (from d2 in list41
from d3 in d2.propIOPointList
select (new BINARY_IO()
{
propX = d3.propX,
propY = d3.propY,
propZ = d3.propZ,
propDir = POINT_DIRECTION_Types.Input,
})).ToList();
I can get the information separately by I want the data to be formatted as an output followed by the inputs, then the next output followed by the inputs, etc.
I have a feeling this is really simple and I just can't get it to work.
Thanks
Upvotes: 0
Views: 368
Reputation: 19203
The easiest way is to transform each item in list41
into an IEnumerable<BINARY_IO>
in the order you listed, then using SelectMany
to flatten the resulting IEnumerable<IEnumerable<BINARY_IO>>
.
var flat =
(from d2 in list41
select
Enumerable.Repeat(
new BINARY_IO {
propX = d2.propOutputPoint.propX,
propY = d2.propOutputPoint.propY,
propZ = d2.propOutputPoint.propZ,
propDir = POINT_DIRECTION_Types.Output}, 1)
.Concat(
from d3 in d2.propIOPointList
select new BINARY_IO {
propX = d3.propX,
propY = d3.propY,
propZ = d3.propZ,
propDir = POINT_DIRECTION_Types.Input}))
.SelectMany(i => i)
.ToList();
Note that I use Enumerable.Repeat(v, 1)
to get a singleton, there are other methods as well.
Additionally you could inline the call to SelectMany
but at that point you might want to switch away from query syntax and just use a manual call to Select
for the second from
/select
.
Upvotes: 1
Reputation: 4655
To flatten a list of list in LINQ, use .SelectMany
var flattenedList = list1.SelectMany(i => i.PropertyThatIsAList)
Many similar questions, for example : Flatten List in LINQ
Upvotes: 1