Why?
In Dynamo you get to deal a lot with lists. In many situations the core nodes are enough and you can build most of the need functionality with them. However this in some cases turns out to be extremely tedios and it removes the focus in the script from it’s actual value to the side helpets. For the functionalities that lack creating a custom node is the best option.
For this node I used python (at a time where I didn’t knew C#).
Description
Reverse Flatten is a custom node that actually does exactly the opposite of what the core node Flatten does. The difference (beside the implementation) is that it starts from the last level of the multi dimensional list instead of starting at the first level.
The image below proves this:
Solution
The code of achieving this is not complicated, It makes use of 3 parts:
- isIterable – checks if the argument is a list or not
- iterateAndDo – handles iteration of 2 arguments and provides custom lacing options
- makeDo – the actual implementation of Reverse Flatten
import re def isIterable(unit): #this function checks if unit is an array t1 = t2 = False; if(isinstance(unit, (tuple, set, list, dict))): t1 = True; if(hasattr(unit, "__iter__")): iterstr = str(unit.__iter__()); if(re.search("System.Array", iterstr)): t2 = True; return (t1 or t2); def iterateAndDo(elements): if(isIterable(elements)): retList = []; for element in elements: if(isIterable(element)): newElement = []; #because when we want to reiterate, we will exclude first level non array #they would have been already shifted one level up for el in element: if(isIterable(el)): #collect if found #retList.append(iterateAndDo(element)); newElement.append(el); else: retList.append(el); if(len(newElement) != 0): retList.append(iterateAndDo(newElement)); else: retList.append(element); return retList; else: return elements; def makeDo(elements, amount): amt = -1; rf = False; try: #making sure this is an integer. It represents the amount of time the list is reverse flattened amt = int(amount); except: pass; act = actions(); if(amt > 1): rf = elements; for idx in range(amt): #this loop applies the reverse flatten method for amount number of times rf = act.iterateAndDo(rf); elif(amt == 1): #if amount is 1, the process is made once rf = act.iterateAndDo(elements); else: return False; return rf; els = IN[0]; amt = IN[1];
Hi Rami,
In which package I can find the List.ReverseFlatten node?
Thanks!
Hi Rami,
What is the package name of the List.ReverseFlatten node?
Thanks!
Hi,
In the Caribou package.