I’ve been struggling for a while now to get my grasshopper dataTree to a list of lists in Grasshopper.
The reason I want to do this is to be able to serialise my tree to a Json-file with the correct depth, to eventually be able to recreate the correct data structure again (also within other software).
I mean that I would like to be able to interpret any form/structure a tree can occur in.
I would also like to be able to convert that to a list of lists with the correct amount of nesting. However, I would be happy if I would be able to do it with the same dimensions in all the paths, as long as that dimension itself can be varied in.
You’ll have to see more effort when iterating through your data of such a list to figure out the types, but it is doable (the C# 7.0 pattern matching in switch cases is really neat for that, but if(somevar is float f)... else if(somevar is List<object> oblist)... works fine too)
I think you misinterpret data trees?! In my understanding its similar to a dictionary with a list as value and the path as a key. Every time you go deeper in the tree structure you just modify the paths, but technically its two dimensional only.
Right, that is indeed how I see it as well, however, I would like to be able to communicate with dynamo. Dynamo works with classic arrays/nested arrays. This is why I would like to convert the data tree.
I remember reading about nested lists that creating them is very bad coding style. You could create a graph object having nodes, where each node contains a list of t then. This is how I would do it, however I don’t know much about dynamo…
That really depends on the problem and domain, for serialization / data transfer purposes it’s probably not an issue.
Originally I wrote this in order to transfer some four-dimensional data (2D bitmap * RGB values * time) to and from an external Python notebook where it was further processed into a Numpy array.
Here’s the complementary function which turns nested lists into a data tree:
from Grasshopper import DataTree
from Grasshopper.Kernel.Data import GH_Path
from System import Array
def unnest(tree, data, indices=(0,)):
index = 0
values = 
for val in data:
if hasattr(val, "__iter__") and not isinstance(val, basestring):
unnest(tree, val, indices+(index,))
index += 1
tree = DataTree[object]()
I don’t know anything about Dynamo either, but doesn’t it use IronPython too? Just json.dump() on one end, json.load() on the other and you’re all set to go
…well in terms of C#, I should have said. Sure there are situation to break these rules. This is an example when a dynamically typed language like Python having a clear advantage.
In C# a generic list of list is already very unreadable piece of code in my opinion. This is why you don’t see it that much. I also believe that C# in general is not the best language to deal with multidimensional generic data. Functional or semi-functional languages are probably stronger here. The whole topic about datastructures in general is a very underestimated problem. … On the other hand IronPython is written in C#, so what works in Python has to work in C# as well.
I think there are certain Pythoney things like dynamic class/ function definitions that are hard or impossible to do in a compiled language like C#, but you’re right that they eventually end up on the same CLR runtime.
And yeah, C# generics can be pretty gnarly… I was looking up GroupBy and got a headache sifting through this list of overloads
Here’s a quick demo with the python code above, while we’re waiting for the freaky stuff from Peter tree2nest2tree.gh (13.5 KB)
(Still don’t quite understand the insistence on C# for this application - as TomTom pointed out, using nested generic lists is a definite code smell, and having to upcast to List<object> to support arbitrary depth means trouble when further processing. )
In the mean time (adding 3 out options: Lists, Jagged Arrays, Dictionary) here’s the puzzle of the century:
Assume that you get a “snapshot” of a tree (any freaky tree) in a jagged array of type object where rows are the branches and the content (child arrays) is variable (jagged) in Length (kinda a tree). You can store the path at pos 0 as well (for doing the inverse) etc etc. Does this make any sense? (Only In the name of the science I guess).
So we are talking 2 C# things here (tree > jagged , jagged > tree).
All well … except when you attempt to output the thing: GH yields a List of object arrays instead of a single object thingy.
Any light bulb ???
BTW: Giulio’s P thingy doesn’t work with freaky trees with random N of dimensions per path (as is the norm in … er … freaky things).