As an example, in Javascript I can do this:
var test = {a:1,b:2} test.a = 'changed' console.log(test)
a!localVariables( local!test: {a:1,b:2}, local!test["a"]: "changed", local!test )
Gives me this error:Expression evaluation error at function 'localvariables': A variable is incorrectly defined. Parameter: 2. Expected syntax: localvariables(local!a, ..., expr) or localvariables(local!a:10, ..., expr)
So it seems you can't changed a key of a variable in an expression. Is there another way to do this? It seems like such an elementary operation...
Discussion posts and replies are publicly visible
Your main mistake here is assuming Appian expressions are like lines of code that execute in order. Instead they should be thought of as a single code statement that will be flattened and evaluated when run.
Thus the technical answer to your question, "how can I make local!test.a == 'changed'", is to declare local!test.a as "changed" in the first place. This might seem like "the snarky answer" but it's also true. Diclaimer: when we start working in interfaces where users interact, this all changes.
The *real* answer to what you're getting at, though, is probably this: when you want to iteratively transform data in local variables, we declare subsequent local variables to handle iterative values. Assume you're fed your local!test value up front. Now you can call "a!update()" on it, feed in the property you want to swap out to a different value, then feed the different value. If you do this as the expression's output, you'll see a readout of the altered dictionary. If you want to keep that for later use, though, you can store that new value in 'local!test2' (etc).
Thank you!But no I didn't make that assumption. I understood that a lot of code in Appian ran in parallel, but that if a line depends on another line then execution order is enforced due to the dependency.I just had no other way of expressing my need but to show it in a language I'm familiar with but that unfortunately doesn't do the same type of parallel execution.
I was looking for something like that function you mentioned, but I had no idea what to search for and I don't think Appian's documentation is very easy to search though. Now that I'm aware of that function though, my code example can be completed like so:
a!localVariables( local!test: {a:1,b:2}, local!test2: a!update(local!test, "a","changed"), local!test2 )
(There's no Appian language option for code inserted in this forum, so sadly I have to format everything as just "text")So, based on how a!update works, and my lack of evidence showing otherwise, it seems that Appian variables are immutable and you can only declare a new modified variable, but not change the original. Correct?So if I had a large map or dictionary and I wanted to change all the keys, I'd have to make a new map for every individual key/value change? That seems like it could waste a lot of memory / time. You can't edit an existing map in place?Same with a!append(), it returns a new array instead of just adding to the old one. If I try to assemble a large array, the only way I can think of doing it is like so:
a!localVariables( local!test: {1,2,3,4,5,6,7,8,9,10}, local!test2: reduce( fn!append ,{} ,a!forEach(items:local!test,expression:local!test) ) ,local!test3: reduce( fn!append ,{} ,a!forEach(items:local!test2,expression:local!test2) ) ,local!test3 )
console.time('t') var test = [1,2,3,4,5,6,7,8,9,10] ,test2 = test.map(()=>test).reduce((acc, curr, currI, arr) => acc.concat(curr), []) ,test3 = test2.map(()=>test2).reduce((acc, curr, currI, arr) => acc.concat(curr), []) console.log(test3) console.timeEnd('t') // ~10ms
So does Appian really not have mutable objects? They would be much more efficient when trying to transform large datasets imported from external APIs.
aj2000 said:(There's no Appian language option for code inserted in this forum, so sadly I have to format everything as just "text")
For what it's worth, this is a long-standing complaint of mine around here - i've brought it up with a few different folks in charge of Community so far, but despite the suggestion always being met with rather enthusiastic agreement, it's never seemed to actually get addressed. I just choose "Java" as its syntax highlighting comes ~close-ish to SAIL in most uses.
aj2000 said:They would be much more efficient when trying to transform large datasets imported from external APIs.
I'm not sure I really understand your general use case, at least up to your mention of large datasets from external APIs.
I've been doing this >10 years now and honestly I've never had much of an issue with the immutability of Appian data objects - it seems to me almost as if you're starting with a conclusion then working backwards to provide examples that meet it. For instance if you want "array of 10,000 integers" you could simply do enumerate(10000) - in my dev environment that takes 1ms.
For large datasets imported from external APIs i believe the "best practice" recommendation is to throw that data into a process instance and handle it there. In successive process nodes you can change any nature of any particiular item in an array individually or in groups, in a specific order. To be honest though, in all but the biggest and most unruly data sets, it's probably sufficient to just transmute incoming data using expression functionality - it just takes some practice at using Appian's functionality to do it.