Skip to content

Instantly share code, notes, and snippets.

@moritzjacobs
Created January 21, 2019 08:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moritzjacobs/f0c9b8fa3ad0a852efe75986d78ddbf2 to your computer and use it in GitHub Desktop.
Save moritzjacobs/f0c9b8fa3ad0a852efe75986d78ddbf2 to your computer and use it in GitHub Desktop.
/**
* 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