Select to view content in your preferred language

Arcade expression to sort an integer field array and return top 5

389
5
4 weeks ago
BronwynRodgers1
Emerging Contributor

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.

BronwynRodgers1_0-1743576055692.png

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

 

Tags (4)
0 Kudos
5 Replies
CodyPatterson
MVP Regular Contributor

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:

CodyPatterson_0-1743594506467.png

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

0 Kudos
BronwynRodgers1
Emerging Contributor

Hi Cody,

So I took that example from the documentation and adapted it to my situation:

var treeArray = [{ 'NAME': 'Weraiti', 'SCORE': $feature.Weraiti }, {'NAME': 'Yeogi', 'SCORE': $feature.Yeogi },{ '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 }];
function compareSCORE(a,b){
  if (a['SCORE']<b['SCORE'])
    return -1;
  if (a['SCORE']>b['SCORE'])
    return 1;
  return 0;
}
return Sort(treeArray, compareSCORE);
 
The attached file is a screenshot of the result in the Field Maps mobile app - returned all, not sorted.
 
BTW how do I insert the code into these posts with all the code lines, not just as text as I have done this time?
0 Kudos
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

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 )
0 Kudos
BronwynRodgers1
Emerging Contributor

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?

BronwynRodgers1_0-1743663850573.png

 

0 Kudos
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

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.

0 Kudos