0

I have data

{
  "id": 1000,
  "price": "99,01USA", 
},
{
  "id": 1001,
  "price": "100USA", 
},
{
  "id": 1002,
  "price": "780USA", 
},
{
  "id": 1003,
  "price": "20USA", 
},

How I sort order by price (ASC , DESC)

Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73
mr.BaoNC
  • 31
  • 3
  • what do you need? elasticsearch query or php code? – Mohammad Mirsafaei Jan 11 '22 at 05:56
  • According to my understating this should be array of objects [ { "id": 1000, "price": "99,01USA", }, { "id": 1001, "price": "100USA", } ] – Kamran Khalid Jan 11 '22 at 06:02
  • I am using PHP to seach on Elastic Seach – mr.BaoNC Jan 11 '22 at 06:50
  • @mr.BaoNC, So sorting on numeric value is easy in elastic search ... but in your case it is a string, could it be possible to modify your data in `price` to make it into a number ? If this is not a viable solution .... this is going to be quite tricky I am afraid – Paulo Jan 11 '22 at 08:27
  • You can put price-as-a-number in a separate field and use that for sorting if you need prices to look exactly like if your example. – ilvar Jan 11 '22 at 20:15

1 Answers1

1

You can alter it a little to parse price to integer and then sort it

You can create a dynamic sort function that sorts objects by their value that you pass:

function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a,b) {
        /* next line works with strings and numbers, 
         * and you may want to customize it to your needs
         */
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        return result * sortOrder;
    }
}

So you can have an array of objects like this:

var People = [
    {Name: "Name", Surname: "Surname"},
    {Name:"AAA", Surname:"ZZZ"},
    {Name: "Name", Surname: "AAA"}
];

...and it will work when you do:

People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));

Actually this already answers the question. Below part is written because many people contacted me, complaining that it doesn't work with multiple parameters.

Multiple Parameters

You can use the function below to generate sort functions with multiple sort parameters.

function dynamicSortMultiple() {
    /*
     * save the arguments object as it will be overwritten
     * note that arguments object is an array-like object
     * consisting of the names of the properties to sort by
     */
    var props = arguments;
    return function (obj1, obj2) {
        var i = 0, result = 0, numberOfProperties = props.length;
        /* try getting a different result from 0 (equal)
         * as long as we have extra properties to compare
         */
        while(result === 0 && i < numberOfProperties) {
            result = dynamicSort(props[i])(obj1, obj2);
            i++;
        }
        return result;
    }
}

Which would enable you to do something like this:

People.sort(dynamicSortMultiple("Name", "-Surname"));

Subclassing Array

For the lucky among us who can use ES6, which allows extending the native objects:

class MyArray extends Array {
    sortBy(...args) {
        return this.sort(dynamicSortMultiple(...args));
    }
}

That would enable this:

MyArray.from(People).sortBy("Name", "-Surname");
Bhavya Koshiya
  • 1,262
  • 2
  • 8
  • 22