I'm quite new to Arcade scripting and need some assistance, I have developed a Field Maps form to evaluate site suitability for tree cultivars. The trees have suitability scores 0-4 for a range of site characteristics. The scores are then totalled. I want to sort these scores descending and return the top 5 names and scores as a readable list.
I typed this query into Copilot along with the attached subset of my 50 tree cultivars and example scores, and received the following (also in an attached file), which does not work.
// Create an array of field names with their scores
var trees = [
{ "name": "Weraiti", "score": $feature.Weraiti },
{ "name": "Yeogi", "score": $feature.Yeogi },
{ "name": "Yunnan", "score": $feature.Yunnan },
{ "name": "Booth", "score": $feature.Booth },
{ "name": "Awanui", "score": $feature.Awanui },
{ "name": "Aegyptica", "score": $feature.Aegyptica },
{ "name": "Gigantea", "score": $feature.Gigantea },
{ "name": "Glenmark", "score": $feature.Glenmark }
];
// Sort the array by scores in descending order
var sortedTrees = Sort(trees, function(item1, item2) {
return item2.score - item1.score;
});
// Get the top 5 items
var topTrees = Slice(sortedTrees, 0, 5);
// Create a readable list
var readableList = "";
for (var i = 0; i < Count(topTrees); i++) {
readableList += (i + 1) + ". " + topTrees[i].name + " - " + topTrees[i].score + TextFormatting.NewLine;
}
return readableList;
And when pasted into Arcade Playground shows where the error is.
My deadline for this app is fast approaching so I would appreciate a reworked expression that I can apply to my complete tree array.
Many thanks
Hey @BronwynRodgers1
Just from an initial look, and this could be incorrect as I'm going to throw this in my own testing, this all looks correct except for a single missing parenthesis here:
Sort() should be something like this: var sortedTrees = Sort(trees, function(item1, item2))
After another look, I was confused at the break between the function declaration, what you have does look pretty good though, maybe consider mirroring what this function here in the documentation does, while also making sure all values are what you should expect:
var peopleArray = [{ 'NAME': 'Sam', 'AGE': 25 }, {'NAME': 'Bob', 'AGE': 27 },{ 'NAME': 'Emma', 'AGE': 24 }];
function compareAge(a,b){
if (a['AGE']<b['AGE'])
return -1;
if (a['AGE']>b['AGE'])
return 1;
return 0;
}
return Sort(peopleArray, compareAge);
// returns '[{ 'AGE': 24, 'NAME': 'Emma' }, { 'AGE': 25, 'NAME': 'Sam' }, { 'AGE': 27, 'NAME': 'Bob' } ]'
https://developers.arcgis.com/arcade/function-reference/array_functions/#sort
Let me know if that works, I'm continuing my testing as well!
Cody
Hi Cody,
So I took that example from the documentation and adapted it to my situation:
Another method is to make a simple featureset and use the orderby and top methods to get the top 5
var Fields = [
{ 'name':'TreeSpecies' , 'type': 'esriFieldTypeString' , 'length':50 },
{ 'name':'Score' , 'type': 'esriFieldTypeInteger' },
]
var TreeNames = {
'Weraiti':0,
'Yeogi':0,
"Yunnan":0,
"Booth":0,
"Awanui":0,
"Aegyptica":0,
"Gigantea":0,
"Glenmark":0
}
Expects($feature,'*')
var Values = []
for( var N in TreeNames ){
V = { 'TreeSpecies' : N , 'Score': $feature[ N ]
Push( Values , {'attributes': V )
}
var TreeScores = {
'fields' : Fields,
'geometry':'',
'features': Values
}
TreeScores = FeatureSet(Text(TreeScores))
TreeScores = Top(OrderBy(TreeScores,'Score'+'Desc'),5)
var M = ''
for( var row in TreeScores){
M = M +'${row.TreeSpecies} has ${row.Score}'+TextFormatting.NewLine
}
Console( M )
When I dropped that into Arcade playground it identified there was a missing comma somewhere around the Push function. Tried a few inserts without success., Where should it be placed?
Sorry there was a script typo. I was using a different IDE outside of the Arcade and noticed that a couple of lines were missing a bracket.
var Fields = [
{ 'name':'TreeSpecies' , 'type': 'esriFieldTypeString' , 'length':50 },
{ 'name':'Score' , 'type': 'esriFieldTypeInteger' },
]
var TreeNames = {
'Weraiti':0,
'Yeogi':0,
"Yunnan":0,
"Booth":0,
"Awanui":0,
"Aegyptica":0,
"Gigantea":0,
"Glenmark":0
}
Expects($feature,'*')
var Values = []
for( var N in TreeNames ){
var V = { 'TreeSpecies' : N , 'Score': $feature[ N ] }
Push( Values , {'attributes': V } )
}
var TreeScores = {
'fields' : Fields,
'geometry':'',
'features': Values
}
TreeScores = FeatureSet(Text(TreeScores))
TreeScores = Top(OrderBy(TreeScores,'Score'+'Desc'),5)
var M = ''
for( var row in TreeScores){
M = M + Text(row.TreeSpecies) + ' has ' + Text(row.Score)+TextFormatting.NewLine
}
Console( M )
If you are using the arcade playground to test things then this code will need to be reconfigured to whatever test data your are trying to use.