Sorting array of mixed clothing sizes in javascript

Issue

Say I have an array that looks like this:

$array = ['xl', 's', '1', '10', '3', 'xs', 'm', '3T', 'xxl', 'xxs', 'one size'];

I want to sort the array to look like this:

$sortedArray = ['1', '3', '3T', '10', 'one size', 'xxs', 'xs', 's', 'm', 'xl', 'xxl'];

How could I possibly sort this array in javascript?

I can spot a pattern so that helps me get on the right track, but I can’t figure out the sort function. A pattern being all sizes that start with a number are first, ordered numerically (but not sure how ‘3T’ handles that). And then we show ‘one size’, and then we sort the rest (XXS, XS, S, M, L, XL, XXL) based on a predefined order.

Solution

Using sort with userdefined sort algorithm: I parse both both to compare to an Int. Than I look if only one of them is a number than this is before. If both are numbers than I look if both are equal. If so than I take the rest from the string (which is not part of the Int) and compare them alphabetically. Otherwise I compare both Integers.
If none of abouve cases is true than I have my ORDER-array with the confection sizes and I sort for the indexOf this. If there are missing any, you can easily add them.

Extended: Because the sizes are sometimes xxl or XXL I convert them for sorting to lowercases so they are sorted as desired.

Extended 2: Because 2XL would be sorted to the beginning to the numbers I make another trick: After parsing to integer I look if the string is one out of the ORDER-array. If so I set the parsed integer to NaN like there stnds a string. By this the comparison for the keywords takes place for this entry.

Extended 3: Sorting of 0 was false, I added it to the begin (like OP’s proposal).

array = ['XL', 's', '1', '10', '2xl', '3', '0', 'xs', 'm', '3T', 'xxl', 'xxs', 'one size'];
const ORDER = ['one size', 'xxs', 'xs', 's', 'm', 'xl', '2xl', 'xxl'];

array.sort((a,b) => {
    a = a.toLowerCase();
    b = b.toLowerCase();
    
    let nra = parseInt(a);
    let nrb = parseInt(b);
    
    if ((ORDER.indexOf(a)!=-1)) nra = NaN;
    if ((ORDER.indexOf(b)!=-1)) nrb = NaN;
  
    if (nrb===0) return 1;
    if (nra&&!nrb || nra===0) return -1;
    if (!nra&&nrb) return 1;
    if (nra && nrb) {
        if (nra==nrb) {
            return (a.substr((''+nra).length)).localeCompare((a.substr((''+nra).length)));
        } else {
            return nra-nrb;
        }
    } else {
        return ORDER.indexOf(a) - ORDER.indexOf(b);
    }
});

console.log(array);

Answered By – Sascha

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published