Created
January 21, 2019 08:33
-
-
Save moritzjacobs/f0c9b8fa3ad0a852efe75986d78ddbf2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* JS utility function to sort an array of clothing sizes (["M", "S", "XL", "XXS"]) | |
* by size and not alphabetically. | |
* | |
* Usage: | |
``` | |
clothingSizesSort(["S", "M", "XL"]) // should === ["XXS", "S", "M", "XL") | |
``` | |
*/ | |
/************* | |
* FUNCTIONS * | |
*************/ | |
/** | |
* sort an array of sizes | |
*/ | |
function clothingSizesSort(sizesRaw) { | |
// pair sizes with their numerical values | |
const sizesWithNumValue = sizesRaw.map(size => { | |
return { | |
raw: size, | |
num: numValue(size) | |
}; | |
}); | |
// and sort them ascending | |
const sizesSortedByNumValue = sizesWithNumValue.sort( | |
(a, b) => a.num - b.num | |
); | |
return sizesSortedByNumValue.map(el => el.raw); | |
} | |
/** | |
* parse a size independent from type | |
*/ | |
function numValue(raw) { | |
const num = parseInt(raw); | |
if (typeof raw === "string") { | |
// raw is numerical string, e.g "45" | |
if (raw !== num.toString()) { | |
return sizeStrValue(raw); | |
} | |
} | |
return num; | |
} | |
/** | |
* convert a size string into a number value for sorting. | |
* XS = 0.1, S = 1, M = 10, L = 100, XL = 10000 and so forth | |
*/ | |
function sizeStrValue(sizeStr) { | |
sizeStr = sizeStr.toLowerCase(); | |
// special case SM = 5 | |
if (sizeStr === "sm") { | |
return 5; | |
} | |
const sizePcs = sizeStr.split(""); | |
const sizeName = sizePcs.pop(); | |
let multiplier = Math.pow(10, sizePcs.length); | |
let sizeValue = 0; | |
switch (sizeName) { | |
case "s": | |
sizeValue = 1; | |
// [...X]S inverts the multiplier | |
multiplier = 1 / multiplier; | |
break; | |
case "m": | |
sizeValue = 10; | |
break; | |
case "l": | |
sizeValue = 100; | |
break; | |
} | |
return sizeValue * multiplier; | |
} | |
/************* | |
* "TESTS" * | |
*************/ | |
const tests = [ | |
{ | |
in: ["45", "42", "38", "46"], | |
expect: ["38", "42", "45", "46"] | |
}, | |
{ | |
in: [45, 42, 38, 46], | |
expect: [38, 42, 45, 46] | |
}, | |
, | |
{ | |
in: ["s", "xxl", "m"], | |
expect: ["s", "m", "xxl"] | |
}, | |
{ | |
in: ["m", "s", "xl", "xxl", "xs", "xxs", "sm", "xxxxxxl", "xxxxxxxxxs"], | |
expect: [ | |
"xxxxxxxxxs", | |
"xxs", | |
"xs", | |
"s", | |
"sm", | |
"m", | |
"xl", | |
"xxl", | |
"xxxxxxl" | |
] | |
}, | |
{ | |
in: ["foo"], | |
expect: ["foo"] | |
}, | |
{ | |
in: [], | |
expect: [] | |
} | |
]; | |
tests.forEach(test => { | |
const result = clothingSizesSort(test.in); | |
const equals = JSON.stringify(result) === JSON.stringify(test.expect); | |
if (equals) { | |
console.log("- ok -"); | |
} else { | |
console.log("- fail -"); | |
console.log(result); | |
console.log("- expected -"); | |
console.log(test.expect); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment