2

I am trying to sort the Strings with number and special characters combination.

But it is giving the wrong order.

<!DOCTYPE html>
<html>
<body>

<p>Click the button to sort the array.</p>

<button onclick="myFunction()">Try it</button>

<p id="demo"></p>

<script>
function MySort(alphabet)
{
    return function(a, b) {
        var index_a = alphabet.indexOf(a[0]),
        index_b = alphabet.indexOf(b[0]);

        if (index_a === index_b) {
            // same first character, sort regular
            if (a < b) {
                return -1;
            } else if (a > b) {
                return 1;
            }
            return 0;
        } else {
            return index_a - index_b;
        }
    }
}

function myFunction() {
  var items = ["AB_UI08","AB_UI03","AB_UI07","AB_UI04","AB_UI05","AB_UI014","AB_UI01","AB_UI09","AB_UI010","AB_UI011","AB_UI012","AB_UI013","AB_UI06","AB_UI016","AB_UI07","AB_UI018","AB_UI019","AB_UI015","AB_UI020","AB_UI02"

],
sorter = MySort('*!@_.()#^&%-=+01234567989abcdefghijklmnopqrstuvwxyz');

console.log(items.sort(sorter));
}
</script>

</body>
</html>

It is giving the below response. ["AB_UI01", "AB_UI010", "AB_UI011", "AB_UI012", "AB_UI013", "AB_UI014", "AB_UI015", "AB_UI016", "AB_UI017", "AB_UI018", "AB_UI019", "AB_UI02", "AB_UI020", "AB_UI03", "AB_UI04", "AB_UI05", "AB_UI06", "AB_UI07", "AB_UI08", "AB_UI09"]

Unsorted array: ["AB_UI08","AB_UI03","AB_UI07","AB_UI04","AB_UI05","AB_UI014","AB_UI01","AB_UI09","AB_UI010","AB_UI011","AB_UI012","AB_UI013","AB_UI06","AB_UI016","AB_UI017","AB_UI018","AB_UI019","AB_UI015","AB_UI020","AB_UI02"]

Expected output: ["AB_UI01", "AB_UI02","AB_UI03", "AB_UI04", "AB_UI05", "AB_UI06", "AB_UI07", "AB_UI08", "AB_UI09", "AB_UI010", "AB_UI011", "AB_UI012", "AB_UI013", "AB_UI014", "AB_UI015", "AB_UI016", "AB_UI17", "AB_UI018", "AB_UI019", "AB_UI020"]

Appreciating your suggestions.

7
  • 1
    which order do you want? Commented Jan 4, 2020 at 9:01
  • btw, i see different items. Commented Jan 4, 2020 at 9:02
  • I would like to see in the ascending order. Commented Jan 4, 2020 at 19:16
  • Edited and updated the output inline with input. Commented Jan 4, 2020 at 19:18
  • 2
    @NinaScholz Edited the query with an unsorted and expected array. Commented Jan 4, 2020 at 19:32

2 Answers 2

4

If you like to sort by groups, like letters and/or digits, you could take sorting with options of String#localeCompare.

var array = ["AB_UI08","AB_UI03","AB_UI07","AB_UI04","AB_UI05","AB_UI014","AB_UI01","AB_UI09","AB_UI010","AB_UI011","AB_UI012","AB_UI013","AB_UI06","AB_UI016","AB_UI07","AB_UI018","AB_UI019","AB_UI015","AB_UI020","AB_UI02"];

console.log(array.sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' })));
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

5 Comments

Thanks for your time @NinaScholz, it helps me to solve my problem.
@Nina Scholz I am interested in the numeric property but I couldn't find any spec specifying the behaviour expected for the numeric property (I mean there is the browser compatibility table on the link you provided but no "spec"). If you have any link to some w3c doc or something, that would be very appreciated!
it's all on the link above.
nah it's just MDN.
ok, opening my eyes, localeCompare to be read not in ecma-262 but ecma-402
1

Given the fact that your word (e.g AB_UI08) seem to be like {letters}{digits} where letters are not digits and digits of the form [0-9]+.

That is: letters==AB_UI and d==08.

Assuming that you want to first sort by letters, then by number.

You can map your words to letters and digits, then in order to compare two words, compare their number iff their letters part are equal.

function toObj(w) {
  const letters = w.match(/^[^\d]+/)[0]
  return { w, letters, d: parseInt(w.replace(letters,'')) }
}

const items = ["AB_UI08","AB_UI03","AB_UI07","AB_UI04","AB_UI05","AB_UI014","AB_UI01","AB_UI09","AB_UI010","AB_UI011","AB_UI012","AB_UI013","AB_UI06","AB_UI016","AB_UI07","AB_UI018","AB_UI019","AB_UI015","AB_UI020","AB_UI02"]

const sorted = items.map(toObj).sort((a,b) => {
  const res = a.letters.localeCompare(b.letters)
  return res !== 0 ? res : a.d - b.d
}).map(x => x.w)

console.log('sorted', sorted)

2 Comments

Great! thanks for the solution, It is working as per my requirement.
@MuralikrishnaKonduru I appreciate you accepting my answer, but the localeCompare as proposed by Nina Scholz may be better (shorter and uses existing api). cheers either way!

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.