Search code examples
javascriptarrayssortingalphanumeric

How to sort an array of objects correctly by an object's alphanumeric name value?


I am trying to sort an array of objects by the name field but the ordering is wrong.

The order I am getting is [1, 10, 11, 2, 20, 21, 3]

Instead of [1, 2, 3, .... 10, 11, 20, 21]

It is sorting but putting 10 ahead of 2

Here is the code I am currently using.

const arr = [
    
    {
        "name": "Action 10",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 11",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 2",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 20",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 21",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 3",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 4",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 5",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 6",
        "color": "transparent",
        "type": "components"
    },
    {
        "name": "Action 1",
        "color": "transparent",
        "type": "components"
    }
]

function sorter(a, b) {
    if (a.name < b.name) return -1;
    if (a.name > b.name) return 1;
    return 0;
}

console.log(arr.sort(sorter));


Solution

  • One could give the numeric sorting option of String.prototype.localeCompare a try ...

    const arr = [{
      name: "Action 10", color: "transparent", type: "components"
    }, {
      name: "Action 11", color: "transparent", type: "components"
    }, {
      name: "Action 2", color: "transparent", type: "components"
    }, {
      name: "Action 20", color: "transparent", type: "components"
    }, {
      name: "Action 21", color: "transparent", type: "components"
    }, {
      name: "Action 3", color: "transparent", type: "components"
    }, {
      name: "Action 4", color: "transparent", type: "components"
    }, {
      name: "Action 5", color: "transparent", type: "components"
    }, {
      name: "Action 6", color: "transparent", type: "components"
    }, {
      name: "Action 1", color: "transparent", type: "components"
    }];
    
    function sorter(a, b) {
      return a.name.localeCompare(b.name, undefined, { numeric: true });
    }
    console.log(arr.sort(sorter));
    .as-console-wrapper { min-height: 100%!important; top: 0; }