Using LINQ to flatten a hierarchical dataset - with a caveat

I have the following dataset I need to flatten into a list:

<row itemID="828518871" locationID="60004165" typeID="9331" quantity="6" flag="4" singleton="0"/>
<row itemID="830476364" locationID="60004165" typeID="649" quantity="1" flag="4" singleton="1">
  <rowset name="contents" key="itemID" columns="itemID,typeID,quantity,flag,singleton">
    <row itemID="1139985051" typeID="6485" quantity="1" flag="22" singleton="1"/>
    <row itemID="1773489170" typeID="11489" quantity="1" flag="5" singleton="1">
      <rowset name="contents" key="itemID" columns="itemID,typeID,quantity,flag,singleton">
        <row itemID="1001694072954" typeID="16357" quantity="1" flag="0" singleton="0"/>
        <row itemID="1001694110421" typeID="16371" quantity="1" flag="0" singleton="0"/>
        ...
      </rowset>
    </row>
  </rowset>
  </row>

(... indicates additional rows and/or levels of nesting; the levels can theoretically nest infinitely.)

The output needs to look like this:

Item { ID = 828518871, Location = 60004165, Type = 9331, Quantity = 6, Flag = 4, Singleton = false }
Item { ID = 830476364, Location = 60004165, Type = 649, Quantity = 1, Flag = 4, Singleton = true }
Item { ID = 1139985051, Location = 60004165, Type = 6485, Quantity = 1, Flag = 22, Singleton = true }
Item { ID = 1773489170, Location = 60004165, Type = 11489, Quantity = 1, Flag = 5, Singleton = true }
Item { ID = 1001694072954, Location = 60004165, Type = 16357, Quantity = 1, Flag = 0, Singleton = false }
Item { ID = 1001694110421, Location = 60004165, Type = 16371, Quantity = 1, Flag = 0, Singleton = false }
...

The catch is that all rows in the output need to have their LocationID correctly set - child rows must get this property from their parent, or their parent's parent, etc.

I've written a recursive method that correctly generates the required output, but I would love to get the same results using only LINQ - is this possible?

Upvotes: 2

Views: 1201

Answers (2)

Magnus
Magnus

Reputation: 46929

I wrote a small extension method called SelectRecursive to the IEnumerable<T> interface some time ago that you can use to create recursive linq queries. http://www.codeproject.com/Tips/80746/Select-Recursive-Extension-method.aspx

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1500385

LINQ isn't generally good with arbitrary recursion. It's fine for flattening one layer of nesting using SelectMany, but recursive solutions will still end up needing to call themselves explicitly. For example, you can write a method which uses LINQ and which calls itself within the query, but you can't easily make LINQ perform the recursion implicitly.

So you may be able to tweak your existing recursive method to use LINQ, but you're unlikely to end up with a completely different structure to the solution.

Upvotes: 6

Related Questions