skip to Main Content

I have a problem with sorting arrays in javascript:

My original array:

let orginalArray = ["Apple","apple","Acrobat","Account","account","Banana","banana","carrot","Carrot",1,2];

Looking for an output like this:

sortedArray = ["Account","Acrobat","Apple","account","apple","Banana","banana","Carrot","carrot",1,2];

This is what I tried:

let sortedArray = orginalArray; 
sortedArray.sort((a, b) => a[keyname].toString().localeCompare(b[keyname].toString(),'en', { caseFirst: 'upper' }));

expecting,

sortedArray = ["Account","Acrobat","Apple","account","apple","Banana","banana","Carrot","carrot",1,2];

2

Answers


  1. Some crazy almost one-liner could be the following.

    The trick is a[0]?.localeCompare(b[0],'en', { caseFirst: 'upper' }) which returns undefined if a is a number or -1 if b is a number or a string which sorted accordingly.

    let originalArray= [3,"Apple",2,1,2,"apple","Acrobat","Account","account","Banana","banana","carrot","Carrot", 0];
    
    const r = originalArray.slice().sort((a, b, c) => 
      (c = a[0]?.localeCompare(b[0], 'en', {caseFirst: 'upper'})) === undefined ? (+b === b ? a - b : 1) : c || a.localeCompare(b, 'en')
    );
    
    console.log(...r);
    Login or Signup to reply.
  2. The following snippet will

    • sort numbers in ascending order after strings
    • all strings that start with an uppercase letter before all strings that start with the same letter in lowercase
    let originalArray = ["Apple","apple","Acrobat","Account","account","Banana","banana","carrot","Carrot",1,2];
    
    function lexCompare(a,b) {
      // if the words start with different letters or 
      // the same letter in the same case
      // do a standard localeCompare
      if (a[0].toUpperCase() !== b[0].toUpperCase() || a[0] === b[0])
        return a.localeCompare(b);
      
      // here we know the two words start with the same letter
      // once in upper and once in lowercase
      // so of a starts with an uppercase letter it has to come first
      // otherwise b has to come first
      return a[0] === a[0].toUpperCase() 
        ? -1
        : 1
    }
    
    let sortedArray = originalArray.slice().sort((a,b) => {
      if (typeof a === typeof b) {
        //if a and b have the same type (ie both are number or string)
        return typeof a === "number"
          ? a - b  //both are numbers, sort them ascending
          : lexCompare(a,b)  //use the sorting function for strings defined above
      } else {
        return typeof a === "number"
          ? 1 // a is a number, b is a string so b has to be sorted before a
          : -1 // b is a number, a is a string so a has to be sorted before b
      }
    })
    
    console.log(sortedArray);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search