How to get second, third, etc largest values in an array using Arcade?

2786
5
Jump to solution
06-29-2020 11:23 AM
RezaTehranifar2
New Contributor III

I am trying to create a popup using arcade that shows in descending order the values across four fields in one feature.

for example, 


namecol1col2col3col4col5
geography A103054020

I would like to have access to an array (or other data types) that I can use in a popup. The user would click on a feature on the popup would show the following:

1. $feature.col4

2. $feature.col2

3. $feature.col5

4. $feature.col1

5, $feature.col3

I have less of an issue presenting in popup, but getting the data ordered. I dont think there is a slice or filter available in arcade.

There is OrderBy function, but that goes down a column vs across a row

so far I have the following in my code to get the max value

var col1 = $feature.col1

var col2 = $feature.col2

var col3 = $feature.col3

var col4 = $feature.col4

var col5 = $feature.col5

var max_val = (col1, col2,  col3, col4, col5)

My logic tells me that I should remove the current max value and then continue to run max function until I have the last one. But I cant seem to find an easy solution. I can run a long if statement, but hoping there is an easier option.

Thanks

Reza

0 Kudos
1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

To expand on Xander Bakker‌'s reply, you could also create a label showing column name and sorted value:

// define Sort comparator returning IsEmpty as least values
function Comp(a,b) { 
    When(
        IsEmpty(a[1]), -1,
        IsEmpty(b[1]), 1,
        IIf(a[1]>b[1],1,-1)
    );
};

// create array of [ColumnName,ColumnValue] arrays and sort on ColumnValue
var arr = [
    ["col1", 10],   // ["col1", $feature.col1],
    ["col2", -30],  // ["col2", $feature.col2],
    ["col3", 5],    // ["col3", $feature.col3],
    ["col4", 40],   // ["col4", $feature.col4],
    ["col5", null], // ["col5", $feature.col5],
];
// arr = Sort(arr, Comp);  // ascending sort
arr = Reverse(Sort(arr, Comp));  // descending sort

// create label showing sorted 'ColumnName : ColumnValue' pairs
var nl = TextFormatting.NewLine;
var lbl = "";
for(var k in arr){
    var i = arr;
    lbl = Concatenate([lbl, Concatenate(i," : ")], nl);
};
return lbl;

returns

col4 : 40
col1 : 10
col3 : 5
col2 : -30
col5 : 

View solution in original post

5 Replies
XanderBakker
Esri Esteemed Contributor

Hi rtehranifar_NYCEDCMGIS ,

Have a look at the expression below:

var col1 = 10; // $feature.col1
var col2 = 30; // $feature.col2
var col3 = 5; // $feature.col3
var col4 = 40; // $feature.col4
var col5 = 20; // $feature.col5

// create array and sort and reverse it
var arr = [col1, col2,  col3, col4, col5];
arr = Reverse(Sort(arr));

// return list of values
var result = "";
var cnt = 0;
for (var i in arr) {
    cnt += 1;
    if (result == "") {
        result = cnt + ". " + arr[i];
    } else {
        result += TextFormatting.NewLine + cnt + ". " + arr[i];
    }
}

return result;

You can use the Sort and Reverse functions to sort an array (descending).

The example above will return this text:

1. 40
2. 30
3. 20
4. 10
5. 5
RezaTehranifar2
New Contributor III

As always, thanks Xander!!

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

To expand on Xander Bakker‌'s reply, you could also create a label showing column name and sorted value:

// define Sort comparator returning IsEmpty as least values
function Comp(a,b) { 
    When(
        IsEmpty(a[1]), -1,
        IsEmpty(b[1]), 1,
        IIf(a[1]>b[1],1,-1)
    );
};

// create array of [ColumnName,ColumnValue] arrays and sort on ColumnValue
var arr = [
    ["col1", 10],   // ["col1", $feature.col1],
    ["col2", -30],  // ["col2", $feature.col2],
    ["col3", 5],    // ["col3", $feature.col3],
    ["col4", 40],   // ["col4", $feature.col4],
    ["col5", null], // ["col5", $feature.col5],
];
// arr = Sort(arr, Comp);  // ascending sort
arr = Reverse(Sort(arr, Comp));  // descending sort

// create label showing sorted 'ColumnName : ColumnValue' pairs
var nl = TextFormatting.NewLine;
var lbl = "";
for(var k in arr){
    var i = arr;
    lbl = Concatenate([lbl, Concatenate(i," : ")], nl);
};
return lbl;

returns

col4 : 40
col1 : 10
col3 : 5
col2 : -30
col5 : 
RezaTehranifar2
New Contributor III

Thanks! appreciate the extra steps

0 Kudos
BrittanyBurson
Occasional Contributor III

Thank you for posting this! This is so helpful for what I am trying to do. However, I wonder if something has changed since you posted it -- I am getting a different return list result when copy/pasting exactly as is? I will keep trying to adapt it with my basic Arcade skills, but if you happen to see this, suggestions are appreciated! Thank you.

BrittanyBurson_0-1658357262778.png

 

0 Kudos