Arcade expressions adding comma to multiple expressions

1934
7
Jump to solution
07-01-2021 01:21 PM
Labels (2)
by Anonymous User
Not applicable

Dear all, 

I have rows of data with abbreviations of Bachelor programs that I want to fully describe in the pop-up. Therefore I made this arcade expression for each bachelor program:

var txt = Split($feature.Opleiding, '/')
if (IndexOF(txt, 'BA') > -1) {
    return 'Bedrijfskunde en agribusiness'
}

Sometimes a row has multiple bachelor programs active (i.e. BA/TA). In the Pop-Up all expressions are active, see screenshot. If the program is not in the dataset, it will not be shown.

Screenshot 2021-07-01 221550.png

This way, both studies will show up, but without a comma or 'and'. So that is why I added this expression (expression/expr0)

if (Find('/', $feature.Opleiding, 0) > -1) {
    return ', '
}

However three combinations or more from these studies are also possible. Now I randomly put down the expression somewhere in the pop-up. As you might have guessed the comma sometimes will be placed before the bachelor programs or after... 

The question: How could I solve this problem so the comma will be placed in between the corresponding active expressions? 

 

0 Kudos
2 Solutions

Accepted Solutions
jcarlson
MVP Esteemed Contributor

The answer is probably "you can't", at least, not without rewriting some of your expressions, or adding a new expression on top of them.

For your popup to adjust based on what your expressions are returning would be its own expression, and can be handled very nicely with the Concatenate function. Really, though, there's no reason for those expressions to all be separate. Consider the following code:

var rep_dict = {
    'BA': 'Bedrijfskunde en agribusiness',
    'SE': 'Something Else',
    'AT': 'Another Thing'
    // and so on
}

var prog_arr = Split($feature.Opleiding, '/')

for(var a in prog_arr){
  for(var k in rep_dict){
        prog_arr[a] = Replace(prog_arr[a], k, rep_dict[k])
    }
}

return Concatenate(prog_arr, ', ')

Running this on a test value of 'SE/AT/BA' returns

 Something Else, Another Thing, Bedrijfskunde en agribusiness

 

- Josh Carlson
Kendall County GIS

View solution in original post

jcarlson
MVP Esteemed Contributor

So, the issue seems to be that nested for k in... loop. It's going through and replacing strings, and I imagine, in ascending order. So it's looking for "4", for example, and it will recognize a match in 24, 34, 47, etc., since the actual string exists.

Two ways to get around this come to mind.

Option 1: Reverse sort your basin names so that single-digit values are replaced last, ensuring that they only trigger on values not caught be two-digit values.

Option 2: Use the basin values as keys. Remember that dict['key'] returns the value in that key.

var splits = Split($feature.Subbasin, ',')

for(var a in splits){
  splits[a] = basinNames[splits[a]]
}

See how that does.

- Josh Carlson
Kendall County GIS

View solution in original post

7 Replies
jcarlson
MVP Esteemed Contributor

The answer is probably "you can't", at least, not without rewriting some of your expressions, or adding a new expression on top of them.

For your popup to adjust based on what your expressions are returning would be its own expression, and can be handled very nicely with the Concatenate function. Really, though, there's no reason for those expressions to all be separate. Consider the following code:

var rep_dict = {
    'BA': 'Bedrijfskunde en agribusiness',
    'SE': 'Something Else',
    'AT': 'Another Thing'
    // and so on
}

var prog_arr = Split($feature.Opleiding, '/')

for(var a in prog_arr){
  for(var k in rep_dict){
        prog_arr[a] = Replace(prog_arr[a], k, rep_dict[k])
    }
}

return Concatenate(prog_arr, ', ')

Running this on a test value of 'SE/AT/BA' returns

 Something Else, Another Thing, Bedrijfskunde en agribusiness

 

- Josh Carlson
Kendall County GIS
by Anonymous User
Not applicable

Hi Josh Carlson,

Of course thanks. I wasn't sure you could make dictionaries in Arcade and this is obviously way cleaner. Thank you very much for the quick reply!

0 Kudos
erica_poisson
Occasional Contributor III

Hi @jcarlson -

I know this is a few years old, but hoping you might be able to assist. I came across this solution and it looked like it would fit the bill for my problem, however I am experiencing a strange output and am baffled. 

Problem: I have a hosted feature layer that is managed via Survey123. One of the select_multiple questions stores codes for each selected subbasin. These codes are not helpful in a pop-up, so I wanted to use Arcade to replace the code with the subbasin name. 

I am not getting an error, but the returned values are incorrect when I compare the stored subbasin codes with the reported subbasin names in the pop-up. 

My code is:

var basinNames = {
    '1': 'Asnebumskit (Mill St)',
    '2': 'Asnebumskit (Princeton)',
    '3': 'Asnebumskit Pond',
    '4': 'Babcock Brook',
}
// and so on - this is a sample of code list, which contains 212 values

var splits = Split($feature.Subbasin, ',')

for(var a in splits){
  for(var k in basinNames){
        splits[a] = Replace(splits[a], k, basinNames[k])
    }
}

return Concatenate(splits, ', ')

 

For example, one record has stored values in the Subbasin attribute field of: 23,40,44,65. These codes correspond with:

erica_poisson_0-1686330678689.png

But instead, my returned value in the pop-up is:

erica_poisson_2-1686330774395.png

 

Even in a situation where only one subbasin was selected the returned subbasin from the Arcade script is incorrect. In this example, there was only one subbasin selected so the name (from domain label) shows up for "Subbasin(s)" in bottom row (65 = this option) and you can see the incorrect name returned in the first row:

erica_poisson_3-1686330922197.png

Do you have any suggestions? I will keep working on this, but if you see something please let me know!

Thank you,

Erica
0 Kudos
jcarlson
MVP Esteemed Contributor

Strange! I looks like it's somehow evaluating per digit? Notice how in your longer example, you get "Babcock BrookBabcock Brook" when the value should be "44". I'm guessing 4 = "Babcock Brook" in your domain? Following that line of thought, I would guess that "Ball Brook" = 5?

- Josh Carlson
Kendall County GIS
0 Kudos
erica_poisson
Occasional Contributor III

Ah yes! That is exactly what's happening. My select_multiple field is a string w/ length of 2. This was an exercise in bringing to region's data together - one region used numeric codes 1 to 90 and the other used two-letter abbreviations. 

When I look at an example that has comma separated two-letter abbreviations, the code appears to work properly. The correct subbasin names are returned and there are no odd duplicates. 

Any idea how to get around this? 

Thank you!

Erica
0 Kudos
jcarlson
MVP Esteemed Contributor

So, the issue seems to be that nested for k in... loop. It's going through and replacing strings, and I imagine, in ascending order. So it's looking for "4", for example, and it will recognize a match in 24, 34, 47, etc., since the actual string exists.

Two ways to get around this come to mind.

Option 1: Reverse sort your basin names so that single-digit values are replaced last, ensuring that they only trigger on values not caught be two-digit values.

Option 2: Use the basin values as keys. Remember that dict['key'] returns the value in that key.

var splits = Split($feature.Subbasin, ',')

for(var a in splits){
  splits[a] = basinNames[splits[a]]
}

See how that does.

- Josh Carlson
Kendall County GIS
erica_poisson
Occasional Contributor III

Hi Josh - 

That modified code snippet worked perfectly and now is returning the proper values. 

Thank you so much!

Erica