0

I have a JS array in following structure:

Array(
    [0] => Array(
        reference : "8926"
        name : "xyz1"
        id_product : "78"
    )
    [1] => Array(
        reference : "11588"
        name : "xyz2"
        id_product : "21"
    )
    [2] => Array(
        reference : "119"
        name : "xyz3"
        id_product : "135"
    )
)

I needed to sort this array using the reference key, I have done it using multisort function;

But the problem is : even though reference is numeric but in the array structure it is defined as string and hence instead of sorting like: 119, 8926, 11588 it is sorting it like 11588 119 8926, i.e., like string.

I cannot re-structure the array because I receive it through an API, is there anyway to sort it numerically without having to recreate it in numeric data type separately (because I have to pass the array forward in same format & hence double-conversion will make the script hectic)?

PS - Current sorting (non-numeric) is done using this function.

3
  • recommendation: sort on length of string and then resolve ties using the value of the string. Commented Jun 7, 2017 at 12:32
  • 2
    Convert the strings to numbers in the sort comparator function. Commented Jun 7, 2017 at 12:33
  • Please post JS array structures as JSON. Commented Jun 7, 2017 at 12:35

4 Answers 4

4

You can convert both parameters from string to number using unary plus + operator inside sort() function.

var data = [{"reference":"8926","name":"xyz1","id_product":"78"},{"reference":"11588","name":"xyz2","id_product":"21"},{"reference":"119","name":"xyz3","id_product":"135"}]

data.sort((a, b) => +a.reference - +b.reference);
console.log(data)

Sign up to request clarification or add additional context in comments.

3 Comments

Wow! This was so simple yet magical, just one question, where & how are you defining the data-type as numeric, is that those '+' signs?
Yes + with try to convert string to number as you can see here jsfiddle.net/Lg0wyt9u/1967
Ah, never knew that. Thanks a lot =)
1

Try this:

let a = new Array(
    {
        reference : "8926",
        name : "xyz1",
        id_product : "78"
    },
    {
        reference : "11588",
        name : "xyz2",
        id_product : "21"
    },
    {
        reference : "119",
        name : "xyz3",
        id_product : "135"
    }
);

a.sort((a, b) => {
  return Number(a.reference) - Number(b.reference);
});

Comments

1

I suggest to upgrade the used library a bit for using it with numerical values.

var x = is_numeric ? +a[columns[index]] : a[columns[index]].toLowerCase(); // <-- this line
var y = is_numeric ? +b[columns[index]] : b[columns[index]].toLowerCase(); // <-- this line
//                   ^ add this unary plus to get a numerical value istead of a string

var helper = {
    arr: {
        /**
    * Function to sort multidimensional array
    *
    * param {array} [arr] Source array
    * param {array} [columns] List of columns to sort
    * param {array} [order_by] List of directions (ASC, DESC)
    * returns {array}
    */
        multisort: function (arr, columns, order_by) {
            if (typeof columns == 'undefined') {
                columns = []
                for (x = 0; x < arr[0].length; x++) {
                    columns.push(x);
                }
            }

            if (typeof order_by == 'undefined') {
                order_by = []
                for (x = 0; x < arr[0].length; x++) {
                    order_by.push('ASC');
                }
            }

            function multisort_recursive(a, b, columns, order_by, index) {
                var direction = order_by[index] == 'DESC' ? 1 : 0;

                var is_numeric = !isNaN(a[columns[index]] - b[columns[index]]);

                var x = is_numeric ? +a[columns[index]] : a[columns[index]].toLowerCase(); // add plus
                var y = is_numeric ? +b[columns[index]] : b[columns[index]].toLowerCase(); // add plus
                //                   ^ add this unary plus to get a numerical value istead of a string

                if (!is_numeric) {
                    x = helper.string.to_ascii(a[columns[index]].toLowerCase(), -1),
                    y = helper.string.to_ascii(b[columns[index]].toLowerCase(), -1);
                }

                if (x < y) {
                    return direction == 0 ? -1 : 1;
                }

                if (x == y) {
                    return columns.length - 1 > index ? multisort_recursive(a, b, columns, order_by, index + 1) : 0;
                }

                return direction == 0 ? 1 : -1;
            }

            return arr.sort(function (a, b) {
                return multisort_recursive(a, b, columns, order_by, 0);
            });
        }
    }
};

var array = [{ reference: "8926", name: "xyz1", id_product: "78" }, { reference: "11588", name: "xyz2", id_product: "21" }, { reference: "119", name: "xyz3", id_product: "135" }];

console.log(helper.arr.multisort(array, ['reference'], ['ASC']));
console.log(helper.arr.multisort(array, ['reference'], ['DESC']));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0

Try with parseFloat its convert the string to number.Then sorting with ASC order

var Arr = [{"reference":"8926","name":"xyz1","id_product":"78"},{"reference":"11588","name":"xyz2","id_product":"21"},{"reference":"119","name":"xyz3","id_product":"135"}]

Arr.sort((a, b) => parseFloat(a.reference) - parseFloat(b.reference));
console.log(Arr)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.