0

I need to sort a JSON array by a value which is nested. Here is the routine I am using and it always returns 0. The field value I want to sort on is advancedoptions.storeId.

orders.sort(GetSortOrder("advancedOptions.storeId"));

function GetSortOrder(prop) {  
    return function(a, b) {  
        if (a[prop] > b[prop]) {  
            return 1;  
        } else if (a[prop] < b[prop]) {  
            return -1;  
        }  
        return 0;  
    }  
}

I want to sort the JSON by storeId:

{
    "orders": [
        {
            "orderId": 415354051,
            "advancedOptions": {
                "storeId": 376480
            }
        },
        {
            "orderId": 415172626,
            "advancedOptions": {
                "storeId": 375780
            }
        },
        {
            "orderId": 414286558,
            "advancedOptions": {
                "storeId": 376480
            }
        },
        {
            "orderId": 412403726,
            "advancedOptions": {
                "storeId": 376480
            }
        }
    ]
}

Correct sort order should be:

"orderId": 415172626,
"orderId": 415354051,
"orderId": 414286558,
"orderId": 412403726,
phuzi
  • 12,078
  • 3
  • 26
  • 50
David
  • 55
  • 6
  • FYI, JSON is a *textual representation of an object* (the result of Serialization). What you have here is an object, or a Javascript object if you want; there are no JSON objects. – Peter B Aug 22 '19 at 09:44

4 Answers4

0

It's the prop you're passing in, you can't access a nested property in an object how you're doing it a["advancedOptions.storeId"]. You need to do something like a["advancedOptions"]["storeId"]. The reason why your function always returns 0 is because a["advancedOptions.storeId"] is always returning undefined not satisfying your if statement.

phuzi
  • 12,078
  • 3
  • 26
  • 50
Dan Starns
  • 3,765
  • 1
  • 10
  • 28
0

function GetSortOrder(select) {
  return function(a, b) {
    const propA = select(a);
    const propB = select(b);
    if (propA > propB) {
      return 1;
    } else if (propA < propB) {
      return -1;
    }
    return 0;
  };
}

const orders = [
  { advancedOptions: { storeId: 34 } },
  { advancedOptions: { storeId: 342 } },
  { advancedOptions: { storeId: 3 } },
];

orders.sort(GetSortOrder(function (i) { return i.advancedOptions.storeId }));

console.log(orders);
Maxim Pyshko
  • 551
  • 4
  • 14
  • This code is for a google app script which supports ES5. I cannot use the arrow function technique (which I am not familiar with) what would this look like in the old Function expression way? – David Aug 22 '19 at 14:28
0

As mentioned, you can't access nested properties when using the bracket notation object[property]. You need to apply brackets for each layer of nesting, like object[property][propery]. When you're calling a[advancedOptions.storeId], it is returning undefined, as the correct syntax to access storeId using the bracket notation is a[advancedOptions][storeId].

If you only need to sort by one property, why not use:

orders.sort((a, b) => a.advancedOptions.storeId > b.advancedOptions.storeId)

Ben
  • 27
  • 2
  • This code is for a google app script which supports ES5. I cannot use the arrow function technique (which I am not familiar with) what would this look like in the old Function expression way? – David Aug 22 '19 at 14:18
0

Try this to have the data sorted by storeId

ordersData.orders.sort((a,b) => 
      a.advancedOptions.storeId < b.advancedOptions.storeId ? -1 : a.advancedOptions.storeId > b.advancedOptions.storeId ? 1 : 0
    );

var ordersData = {
    "orders": [
        {
            "orderId": 415354051,
            "advancedOptions": {
                "storeId": 376480
            }
        },
        {
            "orderId": 415172626,
            "advancedOptions": {
                "storeId": 375780
            }
        },
        {
            "orderId": 414286558,
            "advancedOptions": {
                "storeId": 376480
            }
        },
        {
            "orderId": 412403726,
            "advancedOptions": {
                "storeId": 376480
            }
        }
    ]
}
ordersData.orders.sort((a,b) => 
  a.advancedOptions.storeId < b.advancedOptions.storeId ? -1 : a.advancedOptions.storeId > b.advancedOptions.storeId ? 1 : 0
);
console.log(ordersData);
amyd
  • 7
  • 4