Skip to content

Instantly share code, notes, and snippets.

@mLuby
Created December 13, 2018 21:28
Show Gist options
  • Save mLuby/57ddc8d9d8271c5c7fef30c47dcac034 to your computer and use it in GitHub Desktop.
Save mLuby/57ddc8d9d8271c5c7fef30c47dcac034 to your computer and use it in GitHub Desktop.
list.sort(orderBy(["first", "second", "…", "penultimate", "last"])
// Allows user to list some (but not all) items to be sorted in the specified order.
// If the ellipsis character … (option-; on Mac) is present, can specify order of things to go after everything else.
const debug = false ? console.log : ()=>{}
console.log(["!","o","r","s","d","e","t"].sort(orderBy(["s","o","…","e","d","!"]))) // s o r t e d !
console.log(["b","c","a"].sort(orderBy(["c"]))) // c b a
function orderBy (ordering) { return (a, b) => { // columns specified in orderOfColumns come first, then other columns
const rest_index = ordering.indexOf("…") === -1 ? Infinity : ordering.indexOf("…")
const a_index = ordering.indexOf(a)
const b_index = ordering.indexOf(b)
const A_ORDERED = a_index + 1
const B_ORDERED = b_index + 1
const A_FIRST = A_ORDERED && a_index < rest_index
const B_FIRST = B_ORDERED && b_index < rest_index
const A_LAST = A_ORDERED && a_index > rest_index
const B_LAST = B_ORDERED && b_index > rest_index
const SORT_NORMALLY = a - b
const SORT_BY_ORDER = a_index - b_index
const SORT_A_BEFORE_B = -1
const SORT_B_BEFORE_A = 1
if (A_ORDERED && B_ORDERED) {
if (A_FIRST && B_FIRST) { debug(`${a} A_FIRST, ${b} B_FIRST -> SORT_BY_ORDER`); return SORT_BY_ORDER }
if (A_FIRST && B_LAST) { debug(`${a} A_FIRST, ${b} B_LAST -> A_BEFORE_B`); return SORT_A_BEFORE_B }
if (A_LAST && B_FIRST) { debug(`${a} A_LAST, ${b} B_FIRST -> B_BEFORE_A`); return SORT_B_BEFORE_A }
if (A_LAST && B_LAST) { debug(`${a} A_LAST, ${b} B_LAST -> SORT_BY_ORDER`); return SORT_BY_ORDER }
throw (`Impossible ordering ${a} ${b} ${ordering}`)
}
if (A_FIRST) { debug(`${a} A_FIRST, ${b} B_UNORDERED -> A_BEFORE_B`); return SORT_A_BEFORE_B }
if (A_LAST) { debug(`${a} A_LAST, ${b} B_UNORDERED -> B_BEFORE_A`); return SORT_B_BEFORE_A }
if (B_FIRST) { debug(`${a} A_UNORDERED, ${b} B_FIRST -> B_BEFORE_A`); return SORT_B_BEFORE_A }
if (B_LAST) { debug(`${a} A_UNORDERED, ${b} B_LAST -> A_BEFORE_B`); return SORT_A_BEFORE_B }
debug(`${a} A_UNORDERED ${b} B_UNORDERED -> SORT_NORMALLY`)
return SORT_NORMALLY
} }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment