Arcade: my_array[count++]

1333
9
03-10-2022 01:41 AM
Bud
by
Notable Contributor


Regarding this code sample from the attribute rule docs: (Mark another feature as requiring evaluation)

//Updating the substation name marks its transformers as requiring calculation and updates the yearName to the new name and year. 
//To recalculate the facility id on all transformers, mark all associated transformers as requiring calculation.
var fsDevice =  FeatureSetByName($datastore, "Transformer", ["globalid"], false)
var fsDeviceIntersects = Intersects (fsDevice, Geometry($feature))

var transformers = [];
var count = 0;

for (var i in fsDeviceIntersects)
   transformers[count++] = i.globalid;
var newName = $feature.name + " " + Year(Now())
return {
   'result': newName, 
   'calculationRequired': 
       [
          {
              'className':"Transformer",
              'globalIDs': transformers
           }
       ]
   }


How does this line work?  transformers[count++] = i.globalid;

Is it populating a "count" element in the transformers array with a list of global IDs? And then returning the entire transformers array in the result?

If so, I don't think I realized ++ could be used that way. Thanks.

 

9 Replies
KimGarbade
Occasional Contributor III

Yes. It's populating the transformers array with the GlobalIDs of the individual features in the feature set fsDeviseIntersects. It uses the array later to know which transformers it is going to mark as needing calculation. 

JohannesLindner
MVP Frequent Contributor

Re: Arcade: Increment operators (++x and x++) - Esri Community

Legacy Appending

 

var arr = []

// Previously, you had to append elements like this
var i = 0
arr[i++] = "a"
arr[i++] = "b"

// Now, you can also do it like this:
Push(arr, "a")
Push(arr, "b")

 


Have a great day!
Johannes
Bud
by
Notable Contributor

Is there a benefit to using push() vs. ++ ?

0 Kudos
JohannesLindner
MVP Frequent Contributor

Speedwise, no. Push is even slightly slower, though you will only start to realize that when appending multiple hundred thousand elements...

Time in seconds to append x elements to an array

Elements i++ Push 100 0.000 0.000 1000 0.005 0.008 10000 0.026 0.027 100000 0.126 0.177 1000000 1.417 1.727

For most use cases, you won't need that many elements. Then it comes down to preference in writing and reading the code.

For example, I think i++ looks cleaner, so I might use that in small expressions, even if it takes up an extra line to declare the index variable.

But in some of my longer expressions, I'm appending to multiple arrays throughout the code. This means that I'd have to declare an index variable for all of the arrays, and I'd have to remember which belongs to which array or make the names more descriptive ("i_array_3" vs. "k"), which makes the code harder to write and read. So for that I use Push, because then it's completely clear to which array you are appending an element.

And because I don't want to switch between the two styles in my project, I stick with Push.


Have a great day!
Johannes
Luke_Pinner
MVP Regular Contributor

That's the ++ increment operator.

If used postfix, with operator after operand (for example, x++), the increment operator increments and returns the value before incrementing.

So count++ means get current value of count variable then increment it. 

The code you refer to starts with an empty array (transformers = []) and an zero index (count = 0). It then loops through the objects i in fsDeviceIntersects and assigns i.globalid to the transformers array at index count, then increments count by 1 before the next iteration.

It's doing the same as this:

 

var transformers = [];
var count = 0;

for (var i in fsDeviceIntersects) {
   transformers[count] = i.globalid;
   count = count + 1;
};

 

 

 

 

by Anonymous User
Not applicable

Is there an ESRI blog/course/help page with more information about this concept? I've changed an arcade expression that I found in another blog post to suite my needs and am really struggling to understand how some of it works. Specifically, I am looking for more information about how arr[count] and the operators +=, ++ etc. work so that in the future I can create my own expressions.

 

if ($feature.Type == "Stop Bar"){
var road = FeatureSetByName($datastore,"Road");
var buff = buffer($feature,20,'meter');
var StreetIntersection = intersects(buff,road);

var arr = [];
var count = 0;
for (var f in StreetIntersection){
arr[count] = (f.STREET_NAME)
count +=1;}

var results = Distinct(arr);
var results = Sort(results);
return concatenate(results, " & ");
}

 

 

 

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

For operators (++ etc): https://developers.arcgis.com/arcade/guide/operators/

For data types (eg array): https://developers.arcgis.com/arcade/guide/types/

 

For your example expression:

arr is an array, a collection of elements. You can address a specific element by using its index, starting at 0 for the first element:

var arr = ["a", "b"]
Console(arr[0]) // "a"
Console(arr[1]) // "b"

arr[2] = "c"
Console(arr) // ["a", "b", "c"]

 

+= is an operator that takes a value and adds another value to it. Basically, it's short way of writing this:

var x = 0
x = x + 5  // add 5 to x
x += 5     // do it again, but shorter

 

++ is an operator that increases the variable by 1:

var x = 0

// These all do the same thing:
x = x + 1
x += 1
x++

 

 

So, if we step through your expression:

  • line 6: create an empty array
  • line 7: create a variable that will function as array index
  • line 8: iterate over the featureset
  • line 9: set the array element at the current index
  • line 10: increase the index by 1

You could combine lines 9 and 10:

arr[count++] = (f.STREET_NAME)

 

As a side note: It's best not to use function names like Count as variable names. If you wanted to return the number of elements in your array, normally you would call Count(arr). But you can't do that anymore, because you changed Count from a function to a number.


Have a great day!
Johannes
by Anonymous User
Not applicable

So I would be better off switching count to something like index to make the expression more intuitive.

If I understand correctly and use the first set of intersecting streets (index 0) of MAIN ST, MAIN ST & FIRST ST as an example lines 6-10 do the following:

6. creates and empty array

7. sets an index variable to 0

8. iterates through "Road" features that are within 20m of a "Stop Bar"

9. inserts MAIN ST, MAIN ST, FIRST ST into an array at index 0?

10. adds 1 to the index

Then any duplicated STREET_NAME in the array is removed, they are sorted alphabetically and "FIRST ST & MAIN ST" is added to the attribute table at index 0.

0 Kudos
JohannesLindner
MVP Frequent Contributor

Almost.

 

inserts MAIN ST, MAIN ST, FIRST ST into an array at index 0?

It inserts those values into the array, but not all at index 0, because you increase the index inbetween.

  • line 4: StreetIntersection is now a feature set with 3 features. The values of the STREET_NAME field of those features are "Main Street" (2x) and "First Street"
  • line 8: iterate over StreetIntersections
    1.  count = 0; f.STREET_NAME = "Main Street"; arr = ["Main Street"]
    2.  count = 1; f.STREET_NAME = "Main Street"; arr = ["Main Street", "Main Street"]
    3.  count = 2; f.STREET_NAME = "First Street"; arr = ["Main Street", "Main Street", "First Street"]

 

If you would insert each value at index zero (which would be wrong!), the array would look like this:

  1. ["Main Street"]
  2. ["Main Street"]
  3. ["First Street"]

This is because you are not "inserting" an element as in "take everything that already is in the array and add this element". You are actually setting the element at that index, regardless of what was at that index before. It's just that if the index is equal to the array length, a new element is appended (length 0 -> index 0 -> add first element; length 1 -> index 1 -> add second element).

This means you can also change an element at an index that is not the last element:

var arr = [1, 2, 3]
arr[1] = 5    // [1, 5, 3]
arr[0] = "a"  // ["a", 5, 3]

 

For actually inserting elements, there are the functions Push(array, element) and Insert(array, index, element).

var arr = [1, 2, 3]
Push(arr, 4)  // [1, 2, 3, 4]
var arr = [1, 2, 3]
Insert(arr, 1, 4)  // [1, 4, 2, 3]

 


Have a great day!
Johannes