1

I use this code, thanks to this post:

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;

function sortAlphaNum(a, b) {
        var aA = a.replace(reA, "");
        var bA = b.replace(reA, "");
        if (aA === bA) {
            var aN = parseInt(a.replace(reN, ""), 10);
            var bN = parseInt(b.replace(reN, ""), 10);
            return aN === bN ? 0 : aN > bN ? 1 : -1;
        } else {
            return aA > bA ? 1 : -1;
        }
    }

But what I try to sort is a bit more complex :

I have :

A1
A3
A5
A14
A6-1
A6-2

I expect :

A1
A3
A5
A6-1
A6-2
A14
chepe263
  • 2,774
  • 22
  • 38

2 Answers2

3

You can break it down into 3 sorting criteria: 1) by first character 2) by second number 3) by optional third number (after the dash -) :

const arr = ['A5','A3','A1','A14','A6-2','A6-1'];

const sorted = arr.sort((a,b) => {

  const [[aChar, aN1, aN2],[bChar, bN1, bN2]] = [a,b].map(x => x.match(/([A-Z])|([0-9]+)/gi).map(el => Number(el) || el));

  const c1 = aChar.localeCompare(bChar);
  const c2 = aN1 - bN1;
  const c3 = (aN2 || 0) - (bN2 || 0);

  return c1 || c2 || c3;

});

console.log(sorted);
Leonid Pyrlia
  • 1,594
  • 2
  • 11
  • 14
  • Thanks, but I don't understand the logic, seems better, but I prefer a readable solution – Mévatlavé Kraspek Aug 28 '18 at 15:47
  • @Mévatlavé Kraspek `'A6-1'.match(/([A-Z])|([0-9]+)/gi).map(el => Number(el) || el)` this will convert string `A6-1` into an array `['A', 6, 1]`, or `'A1'` into `['A', 1]` – Leonid Pyrlia Aug 28 '18 at 16:04
  • This part `[[aChar, aN1, aN2],[bChar, bN1, bN2]]` is an ES6 Array Destructuring assignment. In our compare function, If `a` is `A6-1`, and `b` is `A1`, then respectively that assignment allows us to declare those vars in on line – Leonid Pyrlia Aug 28 '18 at 16:09
  • Considering all the above-mentioned, `[[aChar, aN1, aN2],[bChar, bN1, bN2]] = [['A', 6, 1], ['A', 1]]`, `aChar` will be equal to `A`, `bChar` - `A`, `aN1` - 6, `bN1` - 1, `aN2` - 1, `bN2` - `undefined` (since there is no third number after dash) – Leonid Pyrlia Aug 28 '18 at 16:11
  • All of that allows us to break it all down into separate criteria: for character comparison we use `localeCompare` (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare; for numeric - simple subtraction (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Description) – Leonid Pyrlia Aug 28 '18 at 16:18
  • Better edit your post with this relevant informations :) – Mévatlavé Kraspek Aug 28 '18 at 16:19
  • @Mévatlavé Kraspek ++ – Leonid Pyrlia Aug 28 '18 at 16:25
1

With the reference of https://stackoverflow.com/a/4340339/4225796 and thanks to @Leonid Pyrlia and as per your question you have refereed same so using the same example for reference,

we can remove the - and number after - by str.replace(/-.*/g, "");

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
var removeDash = /-.*/g;

var arr = ['A5','A3','A1','A14','A6-2','A6-1'];

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

function sortAlphaNum(a, b) {

a= a.replace(removeDash, "");
b= b.replace(removeDash, "");

  var aA = a.replace(reA, "");
  var bA = b.replace(reA, "");
  if (aA === bA) {
    var aN = parseInt(a.replace(reN, ""), 10);
    var bN = parseInt(b.replace(reN, ""), 10);
    return aN === bN ? 0 : aN > bN ? 1 : -1;
  } else {
    return aA > bA ? 1 : -1;
  }
}
Manasi
  • 765
  • 6
  • 17