Function.Apply: different functions for different arguments

I have been looking for a method to apply different functions to different arguments.
Of course one can apply several functions to all arguments, and then pick the correct results afterward, but to save on processing power, I thought it should be possible to only apply certain functions to relevant elements.

Making a list of the correct functions is pretty easy, it can be done (as seen in the image below) by simply having functions run through an If node. The problem arises however, when these functions will be fed into the Function.Apply node.

As seen here, all functions are applied to every single argument:

My desired result (in this situation) would be a single list of {11,19,31}. But this creates basically creates a cross product rather than one desired list.

Function.Apply does not have levels or different types of lacing, so I’m not sure if this could be tackled differently, if it’s even posssible.

I am aware that there are simpler ways to approach this, such as filtering the elements and then leading them through “different” paths of formulas. But I still encounter situations where this would be more useful.

1 Like

You seem to be using a really old version of Dynamo.
In the version that I’ve used setting lacing to longest on the If node should work.

That is true, I’m still using Dynamo 1.3 as I’m still dealing with projects that run in old versions of Revit.

I would like you to actually look back at what my question was though, considering you did not answer it at all. I did specifically care about doing the +1 or -1 to a number. I’m interested in applying certain formulas. The simple set up serves more as a proof of concept for more complicated functions.

This problem is true for Dynamo 2.x too.

Can you explain a little more on why the formula has to be passed on before being run as opposed to executing the function and then returning the result? Is it just a computing concern? Have you tried with ScopeIf?

First of all: it just means that it doesn’t have to double work. Currently I’d be in a situation where I have several processes running simultaniously, and then only picking part of the results for both.
The way I often deal with this now is by splitting them up to start with, and then sorting them back together, but sometimes I’d have to do this several times based on several conditions and it can become a hassle.

Second: It’s often very hard to make Dynamo not do something. I already mentioned you can filter things out, but there will still be situations where you will end up with some empty or wrong inputs which will create warnings . Easiest thing is to just let them output a null and generate a warning with no actual consequences but I’d prefer to save for situations where things are actually going wrong

I have not yet found this to be necessary, but quite often I wish I could. If it’s not possible, so be it.

I suppose you are looking for an Imperative workflow (If-else, for and while loops etc). That can be done with Design Script in a code block. With nodes, as @Nick_Boyts suggested, you might have to look at the ScopeIf node.

I haven’t used ScopeIf or Function.Apply in a very very long time, so don’t recollect how they work.

May not be the solution you’re looking for (and I’m quite sure I’m not addressing your specific issue), but you should be able to use complicated functions too with just the If node.

3 Likes

I’m not sure if this will work for your application, but I can solve the simple proof of concept by switching the order of the “Function.Apply” and “If” nodes:

Of course, you need to add an additional Function.Apply node for each branch of the script.

1 Like

2017 to 2019 works with 2.0.3, so… You’re using Revit 2016 or older!!!

That’s the trifecta of missing security patches, no support, and lost productivity due to not getting new features and big fixes.

It’s time to pull the plug and modernize (and keep modernizing). Doing so will pay for itself.

2 Likes

maybe this will be helpful:

2 Likes

I agree, it’s a shame I have no say in that, there’s like one old project running which does hold a lot of other things back.

1 Like

In both your and @Frank_Loftus’ example all arguments are still running through both functions.
This is the step I’m trying to avoid.

I hadn’t really used Function.Apply until recently. I found it to be useful recently because I actually can choose to make use of one function or another:

This can be useful, especially when it concerns functions that are somewhat time consuming or simply because you really don’t want them to happen.

But this is quite limited as it can only do one or the other function on all arguments.

While not a massive limitation I find it somewhat surprising. It’s perfectly possible to run a function on a list of arguments, a single argument that is a list, a list of lists… Apparently now a cross product of arguments and functions. The Function.Apply node creates this cross product as a standard. While I understand it’s a different beast when you’re dealing with functions, applying one function on each argument would be in line with how most other nodes work in Dynamo.

I played around with it, and after making a small alteration it works!

Thanks a lot!

I will be playing around with how far I can push this.

(Yes, I did go to Dynamo 2.x)

3 Likes

while __ApplyList may not show up in autocomplete, the function should be fully accessible without having to redefine it. Did that not work?

1 Like

I missed that, but you are correct!

This is perfect. Thanks a lot!

The initial one downside of this method I found was that I couldn’t get it to straight up accept lists as a single input to deal with. This however can quite easily be circumvented by making a List.GetItemAtIndex node part of the function and give an index as an argument.


In the example above it checks whether the input is a list or a single number (simply counting the length), and doubles single number and gets the average of lists.
Obviously something that can be done more easily (and I don’t really see why you’d want to do it at all) but I think it’s good proof of concept.

1 Like