'AND'/'OR' Statement in Arcade Expression for Labeling in Portal for ArcGIS

5928
5
03-17-2020 03:45 PM
AdamBakiera
Occasional Contributor

I am trying to write an Arcade expression for symbology I need in a web map in Portal. The problem I can't overcome at the moment is that the symbology needs to be based on 3 different fields. I've attached two text documents in vb script format that detail what exactly needs to fall under which category. There are 'Homes' and there are 'Passings'. For Homes, we need active accounts, certain service ID's, and certain rate schedules. For Passings, we need inactive accounts, certain service ID's, and certain rate schedules. So far, I haven't been able to figure out how to write the expression for these scenarios. I can use the concatenate function and that works, but that leaves me with dozens of combinations, so I'd rather not have to manually go into the symbology editor and adjust them one by one. I'd like to be able to group the combinations into Homes and Passings.

I've seen the below solution in another article, but that would take a while to write out every possible scenario

Is there an easier way to write out this scenario?

Thank you!

Xander Bakker

0 Kudos
5 Replies
BenTurrell
Occasional Contributor III

Hey Adam Bakiera‌,

You could use an AND statement in your if statement to drill down to the level you are after. You will still end up with quite a few different if statements. I would do something like


if(Printed == "Yes" && Worked == "No" && Entered =="No"){

return "Printed"

}

That might make it a bit easier to write.

Happy to discuss further.

Thanks,

Ben


If this answer was helpful please mark it as helpful. If this answer solved your question please mark it as the answer to help others who have the same question.

XanderBakker
Esri Esteemed Contributor

Hi Adam Bakiera ,

You can also consider doing something like this:

var case = $feature.Printed + $feature.Worked + $feature.Entered;
var dct = {"NONONO": "Needs printing", "YESNONO":"Printed", 
           "YESYESNO": "Worked", "YESYESYES": "Entered"};
           
if (HasKey(dct, case)) {
    return dct[case];
} else {
    return "Invalid combination";
}
‍‍‍‍‍‍‍‍‍

What I did is create a dictionary that contains the valid keys (valid combinations of printer, worked and entered) and if the combination "case" is inside that dictionary, you return the text you want. Probably the additional validation of checking if it is inside the dictionary might be redundant, if your data is consistent. In that case you can simplify it to:

var dct = {"NONONO": "Needs printing", "YESNONO":"Printed", 
           "YESYESNO": "Worked", "YESYESYES": "Entered"};
return dct[$feature.Printed + $feature.Worked + $feature.Entered];
‍‍‍

Or even a single line (although it is not very good for readability):

return {"NONONO": "Needs printing", "YESNONO":"Printed", "YESYESNO": "Worked", "YESYESYES": "Entered"}[$feature.Printed + $feature.Worked + $feature.Entered];
0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi Adam Bakiera ,

I noticed you attached two text files with some invalid Arcade expressions. To provide an example of what you can do to avoid endless or statements, see the expression below:

var test = "7";
var arr = ['00', '0', '1', '2', '3', '4', '5', '8', '9', 
           '11', '12', '13', '14', '15', '16', '19', '20', 
           '22', '23', '24', '25', '26', '28', '29', '30', 
           '32', '34', '36', '37', '39', '47', '48', '49', 
           '50', '51', '55', '57', '58', '59', '62', '64', 
           '65', '66', '68', '69', '70', '71', '72', '73', 
           '74', '75', '76', '77', '78', '79', '80', '81', 
           '82', '83', '84', '85', '86', '88', '89', '90', 
           '91', '93', '94', 'Y'];

var i = indexOf(arr, test);
return i != -1;

 

Consider the array "arr" as the list of values you want to test the attribute "ServiceTypecd" against. The IndexOf function will return the location of the value you search for in the list. If it returns the value -1 it means the value is not in the list. 

Also the example based on your text file contains about 70 values for a range of values that seems to be between 0 and 100. If it is easier to test for the opposite, then do that to reduce and optimize your code.

0 Kudos
AdamBakiera
Occasional Contributor

Thank y'all for the quick responses! I went with Ben Turrell‌'s method and I think I got what I'm looking for, at least for the 'Homes' part. Albeit, the expression is very long, but it didn't take all that long to create because of copy and paste. Xander Bakker‌ I should've mentioned that the two text documents attached are not in Arcade format, but in VB. My apologies for leaving that part out. I may use your method for the 'Passings' portion because it will have more options. Also, is this a limitation of the program? I'm trying to get a count of how many 'Homes' I'm getting with my expression but it looks like the data is limited to a sample. 

I know there are way more than 72 by looking at my map.

I've attached the expression I'm using for 'Homes' as well. 

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi Adam Bakiera ,

The statistics you see is as mentioned just a sample of 1000 records and does not represent the entire dataset. I just had a look at your expression and noticed that it had 1444 lines... This is a lot and really not necessary.  For instance at every if statement you check if the Status is "Active". Do this one time at the top and only check for ServiceID and Rate. I would also use arrays (as I showed in an example of a previous reply) to reduce the amount of lines.

I just wonder, why it should be so complex to determine if something is a home based on the data you have. If possible I would revise the data schema used, since it is far from optimal for this purpose. 

0 Kudos