Arcade For Loop & Array

4969
13
Jump to solution
08-02-2022 12:43 PM
ChristineSeidel
New Contributor III

Hi - I'm using ArcPro 3.0.0 and I'm new to Arcade.  Using Calculate Field, I trying to write a bit of Arcade code so it loops thru the values of existing field which has a string of concatenated values (i.e.  -99,1,2).  Where an item in this string does not equal -99, I want to append the value to a new array and then ultimately return the Mean of the NewArray.  So, given -99,1,2 the resulting Mean should = 1.5

So, I've tried the following code but it doesn't work.  It just returns Null values:

var NewArray = []
var OrigArray = split($feature.CONCATENATE_Story_Num, ",")
For (var i in OrigArray) {
  If (i!=-99) {
    NewArray+=OrigArray[i];
    }
}
return Mean(NewArray)

Thanks

2 Solutions

Accepted Solutions
jcarlson
MVP Esteemed Contributor

There are a few things to address with your expression, but you're most of the way there.

First, you're trying to append to the new array the wrong way. Using += works for numbers and strings, but an array needs to be appended to differently. In the latest versions of Arcade you have access to Push, which will insert an item into an array.

Also, if your original field is a string, you'll need to convert those to numbers.

And lastly, when you're looping over an array, you access the individual array items with array[index], not by calling the index directly, which is just an integer.

 Try this:

var NewArray = []
var OrigArray = split($feature.CONCATENATE_Story_Num, ",")

for (var i in OrigArray) {
  If (Number(OrigArray[i]) != -99) {
    Push(NewArray, OrigArray[i]);
    }
}

return Mean(NewArray)

 

Here's my result running it against '-99,1,2':

jcarlson_0-1659470542914.png

 

- Josh Carlson
Kendall County GIS

View solution in original post

KenBuja
MVP Esteemed Contributor

It turns out you don't need a Map function, just a minor modification to the Filter function

var arr = "-99,1,2";

function isGood(i) {i != "-99"}

var newarr = Filter(split(arr,","), isGood);
return Mean(newarr);

View solution in original post

13 Replies
KenBuja
MVP Esteemed Contributor

You can use the Filter function to do this

var arr = [-99,1,2];

function isGood(i) {i != -99}

var newarr = Filter(arr, isGood);
return Mean(newarr)

 

jcarlson
MVP Esteemed Contributor

Oh, I like this! Sometimes I forget about the array functions. Combining this with Map to get the strings to numbers would be really slick.

- Josh Carlson
Kendall County GIS
KenBuja
MVP Esteemed Contributor

It turns out you don't need a Map function, just a minor modification to the Filter function

var arr = "-99,1,2";

function isGood(i) {i != "-99"}

var newarr = Filter(split(arr,","), isGood);
return Mean(newarr);
jcarlson
MVP Esteemed Contributor

Interesting! Now I'm wondering if I had a typo when I tested it originally. Mean seems to cast array members to numbers automatically.

- Josh Carlson
Kendall County GIS
KenBuja
MVP Esteemed Contributor

@jcarlson wrote:

Interesting! Now I'm wondering if I had a typo when I tested it originally. Mean seems to cast array members to numbers automatically.


Yes, which is why your code worked. Otherwise, you would have had to convert the values in OrigArray to a number when you pushed them into NewArray

jcarlson
MVP Esteemed Contributor

D'oh!

@ChristineSeidelI think Ken should get the green checkmark here, he has a much more elegant solution than I, and clearly was more careful in how he wrote his expression. I just got lucky!

- Josh Carlson
Kendall County GIS
ChristineSeidel
New Contributor III

Thanks Ken.  As Josh says, your solution is quite elegant.  Being pretty new to Arcade it was easier for me to follow the logic of the For Loop and building a new array ...but it's great to know more ways around the barn.  Thank you.

- Chris Seidel

Cartographer - Martha's Vineyard Commission

0 Kudos
KenBuja
MVP Esteemed Contributor

That's why Josh's replies are always so helpful. He provides a good amount of background information on why things are happening.

jcarlson
MVP Esteemed Contributor

There are a few things to address with your expression, but you're most of the way there.

First, you're trying to append to the new array the wrong way. Using += works for numbers and strings, but an array needs to be appended to differently. In the latest versions of Arcade you have access to Push, which will insert an item into an array.

Also, if your original field is a string, you'll need to convert those to numbers.

And lastly, when you're looping over an array, you access the individual array items with array[index], not by calling the index directly, which is just an integer.

 Try this:

var NewArray = []
var OrigArray = split($feature.CONCATENATE_Story_Num, ",")

for (var i in OrigArray) {
  If (Number(OrigArray[i]) != -99) {
    Push(NewArray, OrigArray[i]);
    }
}

return Mean(NewArray)

 

Here's my result running it against '-99,1,2':

jcarlson_0-1659470542914.png

 

- Josh Carlson
Kendall County GIS