# Arcade For Loop & Array

926
11
08-02-2022 12:43 PM
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

Tags (5)
2 Solutions

Accepted Solutions
by
MVP Honored 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':

- Josh Carlson
Kendall County GIS
by
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);``````
11 Replies
by
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)``````

by
MVP Honored 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
by
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);``````
by
MVP Honored 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
by
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

by
MVP Honored 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
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

by
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.

by
MVP Honored 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':

- Josh Carlson
Kendall County GIS