I want to symbolize points based on the presence of specific words in a variety of fields. There are 19 fields that hold priority values of either 'High', 'Medium', 'Low', or null. Ideally, what I would like is this:
If any of the fields have a value of 'High', then the symbol category will be 'High' regardless of the number of 'High' values, or whether or not any of the 19 fields have values of 'Medium' or 'Low'
If none of the fields are 'High', then move on to do the same thing for medium, then to low.
My idea was to create an array of the fields, then do a for loop to check for the priority words in the fields. If the word appeared in any of the array fields, then a variable will change from 0 to 1. Then I can do a cascading If statement to get my final categorization. I think my big issue is the for loop, as usual.
// initilize variables for different priority values
var hCount = 0
var mCount = 0
var lCount = 0
// priority fields
var p1 = $feature.Priority_1
var p2 = $feature.Priority_2
var p3 = $feature.Priority_3
var p4 = $feature.Priority_4
var p5 = $feature.Priority_5
var p6 = $feature.Priority_6
var p7 = $feature.Priority_7
var p8 = $feature.Priority_8
var p9 = $feature.Priority_9
var p10 = $feature.Priority_10
var p11 = $feature.Priority_11
var p12 = $feature.Priority_12
var p13 = $feature.Priority_13
var p14 = $feature.Priority_14
var p15 = $feature.Priority_15
var p16 = $feature.Priority_16
var p17 = $feature.Priority_17
var p18 = $feature.Priority_18
var p19 = $feature.Priority_19
// set up array for loop
var priorityFields = [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19]
// Check for the word 'High' as the value in any of the priorityFields
// This is where I am lost
for (var p in priorityFields){
if (p=='High'){ hCount = 1}
else {hCount}
}
// Then do the same thing for 'Medium' and 'Low'
// Finally, compare Count variables. If hCount is above 0, then 'High', if hCount is 0, then check the same for mCXount, etc. I can write this code later.
then if all of the Count variables are 0, the final category is something like 'No Maintenance Needed'.
Solved! Go to Solution.
Check out the function Any. It requires you to create a custom function for checking specific values like this, but it's pretty nice. No need for counts or loops.
var priorities = [
$feature.Priority_1,
// and so on
]
function IsHigh(x){return x == 'High'}
function IsMed(x){return x == 'Medium'}
function IsLow(x){return x == 'Low'}
return When(
Any(priorities, IsHigh), 'High',
Any(priorities, IsMed), 'Medium',
Any(priorities, IsLow), 'Low',
'No Maintenance Needed'
)
Check out the function Any. It requires you to create a custom function for checking specific values like this, but it's pretty nice. No need for counts or loops.
var priorities = [
$feature.Priority_1,
// and so on
]
function IsHigh(x){return x == 'High'}
function IsMed(x){return x == 'Medium'}
function IsLow(x){return x == 'Low'}
return When(
Any(priorities, IsHigh), 'High',
Any(priorities, IsMed), 'Medium',
Any(priorities, IsLow), 'Low',
'No Maintenance Needed'
)
Hey Josh, this works perfectly! I don't have a lot of experience with functions. I can piece together the Any function as part of the return, but I'm wondering if you'd be kind enough to explain the isHigh/isMed/isLow functions. How does that 'x' work in those?
Sure!
The function Any acts against an array. From the Arcade docs:
Tests whether any of the elements in a given array pass a test from the provided function. Returns true if the function returns true for at least one item in the input array.
So, after the array, the other parameter is a function name. Any will essentially loop through the array, apply that function to every item in the array, and tell you if any of them yielded a "true".
In some cases, you can use a built-in function like Boolean or IsEmpty, but for our case, we want to check if any of the values are equal to "High". Since no function exists that does this, we make our own.
In Arcade, we can define our own functions, and when we do that, we use placeholder variable. It might make more sense if you saw a custom function used in a more normal context.
function SaySomething(text, name){
return text + ' ' + name
}
return SaySomething('Hello', 'Zach')
That code would return the text "Hello Zach". The parameters 'text' and 'name' in the function are only being used to define how the function itself works.
So, those functions I defined are taking whatever gets passed into it as the variable x, then simply checks to see if that thing is equal to "High", etc. I could have used anything as the placeholder, I just picked "x".
When you refer to a function in Any, you don't give it any parameters. What it does is run the function against every item in the array, and it inserts each item as the parameter.
If your field names are indeed like that, this should work
var high = false;
var medium = false;
var low = false;
for (var i = 1; i <= 19; i++) {
var fieldName = `Priority_${i}`
if ($feature[fieldName] == 'High') high = true;
if ($feature[fieldName] == 'Medium') medium = true;
if ($feature[fieldName] == 'Low') low = true;
}
When(high, 'High',
medium, 'Medium',
low, 'Low',
'No Maintenance Needed')
Hey Ken, I can definitely see how that code should work. I am getting an error I wouldn't expect:
The field definitely exists, and it looks like the fieldName variable is correctly searching for it, so I'm not quite sure why it wouldn't be finding it. This is in Pro 3.2.2 if that makes a difference.
I had omitted the Expects function. Give this a try
var high = false;
var medium = false;
var low = false;
Expects($feature, '*'); // or you can list out just the field names you need
for (var i = 1; i <= 19; i++) {
var fieldName = `Priority_${i}`
if ($feature[fieldName] == 'High') high = true;
if ($feature[fieldName] == 'Medium') medium = true;
if ($feature[fieldName] == 'Low') low = true;
}
When(high, 'High',
medium, 'Medium',
low, 'Low',
'No Maintenance Needed')