0

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

Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160
Michael
  • 41
  • 1
  • 1
  • 7
  • can we see the declarations of each class involved please (IO_EQUATIONS, INPUT_POINT, OUTPUT_POINT, others?), so I can improve my answer – Bruno Apr 21 '15 at 20:06
  • Rather than a paragraph explaining your model, the model's code would be more helpful. – Cameron Apr 21 '15 at 20:23

2 Answers2

1

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

Community
  • 1
  • 1
Bruno
  • 4,685
  • 7
  • 54
  • 105
  • 1
    This answer is pretty incomplete. Can you show him how to rewrite his example with query syntax that uses `SelectMany`? – Tim S. Apr 21 '15 at 20:03
  • I've tried SelectMany on my List of INPUT_POINT and that works fine but it doesn't include my OUTPUT_POINT in the final list. It feels like I want to select the OUTPUT_POINT and concatenate the list of INPUT_POINT to create the final list I'm looking for. – Michael Apr 21 '15 at 20:25
  • Would it be something like: `list41.SelectMany(eq => eq.INPUT_POINTs, (eq, inputs) => new { OUTPUT = eq.OUTPUT_POINT, INPUTS = inputs).ToList()` – jwatts1980 Apr 21 '15 at 20:28
  • 1
    You could further modify it with a `Select`: `list41.SelectMany(eq => eq.INPUT_POINTs, (eq, inputs) => new { EQ = eq, INPUT = inputs).Select(t => new { OutputPoint = t.OUTPUT, InputX = t.INPUT.X, InputY = t.INPUT.Y, InputZ = t.INPUT.Z).ToList();` – jwatts1980 Apr 21 '15 at 20:32
1

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.

Guvante
  • 18,775
  • 1
  • 33
  • 64
  • That worked perfectly. Listing the single output followed by concatenating the list of inputs was exactly what I was trying to do. – Michael Apr 21 '15 at 20:49