Hi- I wrote a simple arcade script to replace text in a field for the pop-up display and have run into something unusual.
The script will replace the abbreviated name for impairment type with the full name for each hydro feature in the layer.
var impParam = $feature["IMP_PARAM"];
impParam = Replace(impParam, 'FishesBio', 'Fishes bioassessments');
impParam = Replace(impParam, 'Hg-F', 'Mercury in fish tissue');
impParam = Replace(impParam, 'E.coli', 'Escherichia coli');
impParam = Replace(impParam, 'InvertBio', 'Aquatic macroinvertebrate bioassessments');
impParam = Replace(impParam, 'TSS', 'Total Suspended solids');
impParam = Replace(impParam, 'T', 'Turbidity');
return impParam;
Some features have several impairments listed, example:
It works great except that the Replace function will not replace 1 character strings, such as the 'T' for 'Turbidity', AGOL doesn't like it at all and will stall out forcing me to reload the page. Any ideas why I cannot replace a 1 char string or any suggestions for improving the script?
Thanks much!
Kate
I think the issue is that the replacement for 'T' has a 'T' in it, so it creates a sort of endless loop that freezes the page. The 'T' in other values like 'TSS' or 'Total Suspended solids' (depending on the order of the replace statements) will also be replaced, so that's something else to consider. Since Arcade expressions are case sensitive the lower case t's aren't affected.
You could do something like this:
var impParam = $feature["IMP_PARAM"];
impParam = Replace(impParam, 'T', 'turbidity');
impParam = Replace(impParam, 'FishesBio', 'Fishes bioassessments');
impParam = Replace(impParam, 'Hg-F', 'Mercury in fish tissue');
impParam = Replace(impParam, 'E.coli', 'Escherichia coli');
impParam = Replace(impParam, 'InvertBio', 'Aquatic macroinvertebrate bioassessments');
impParam = Replace(impParam, 'turbiditySS', 'Total Suspended solids');
impParam = Replace(impParam, 'turbidity', 'Turbidity');
return impParam;
That's it!! Thank you, Stephen, for taking the time to explain along with an example solution.
Kate
Although the solution provided by Stephen works in your specific case, you should be aware that Replace is not the correct function to solve this. Replace will find and replace any coincidence of the string that you are looking for which potentially may cause unexpected behavior. You actually have a list of values separated by a semicolon. What would be better (although it is more complex) is to test if any of the values in the list exactly matches the list of values that you have. See the example below:
// var impParam = $feature["IMP_PARAM"];
var impParam = "Test; E.coli; TSS; T; InvertBio; turbiditySS; turbidity; FishesBio; Hg-F";
var dict = {
'T': 'turbidity',
'FishesBio': 'Fishes bioassessments',
'Hg-F': 'Mercury in fish tissue',
'E.coli': 'Escherichia coli',
'InvertBio': 'Aquatic macroinvertebrate bioassessments',
'turbiditySS': 'Total Suspended solids',
'turbidity': 'Turbidity'
}
var lst_in = Split(impParam, ';');
var lst_out = [];
for (var i in lst_in) {
var item_in = Trim(lst_in[i]);
var item_out = item_in;
for (var search_txt in dict) {
var replace_txt = dict[search_txt];
if (item_in == search_txt) {
item_out = replace_txt;
}
}
lst_out[i] = item_out;
}
var result = Concatenate(lst_out, "; ");
return result;
In this case I create a dictionary with search and replace values (lines 4 - 12). The code creates a list on line 14 and starts to loop through the items of the list and will validate any value in the dictionary and replace it by the desired one.
At the end (line 28) the items of new list are concatenated to create the output string.
Xander-
Thanks for responding with a 'best practice' solution. You are right, the Replace function is working for my needs but I would rather use the more sophisticated method to ensure this is done right.
I copied and pasted your example script and it does work, but, it returns/replaces everything listed in the var impParam, even Test. Perhaps as a test, this is what it was supposed to do? Any recommendations for returning only the values for each record, such as 'Eschreichai coli; Turbidity' in the first record.
Thanks much-
Kate
I suppose you didn't unquote line 1 and removed line 2. Line 2 I used for testing. Line 1, once unquoted, will read your field.
That's right, amateur script-er here! Thanks, this works great.
Kate
Xander - thanks for the great solution (and many others I've seen!).
I made a slight modification to use the HasKey dictionary method:
var impParam = "Test; E.coli; TSS; T; InvertBio; turbiditySS; turbidity; FishesBio; Hg-F";
var dict = {
'T': 'turbidity',
'FishesBio': 'Fishes bioassessments',
'Hg-F': 'Mercury in fish tissue',
'E.coli': 'Escherichia coli',
'InvertBio': 'Aquatic macroinvertebrate bioassessments',
'turbiditySS': 'Total Suspended solids',
'turbidity': 'Turbidity'
}
var lst_in = Split(impParam, ';');
var lst_out = [];
for (var i in lst_in) {
var item_in = Trim(lst_in[i]);
var item_out = item_in;
if ( HasKey(dict, item_in) ) {
item_out = dict[item_in];
} // else - item_out still equals item_in
lst_out[i] = item_out;
}
var result = Concatenate(lst_out, "; ");
return result;