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 needed functionality with them. However this in some cases turns out to be extremely tedious and it removes the focus in the script from its actual value to the side helpers. 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 know 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.
Solution
The code of achieving this is not complicated. It makes use of 3 parts:
isIterable– checks if the argument is a list or notiterateAndDo– handles iteration of 2 arguments and provides custom lacing optionsmakeDo– 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];