Two solutions - Array.prototype.sort() with closure, and a Quicksort implementation.
Intuition\nThe Javacript Array prototype offers a swap method that takes a comparison function, but it requires the function to take two inputs and then return 
# Intuition\nThe Javacript Array prototype offers a swap method that takes a comparison function, but it requires the function to take two inputs and then return -1 (a < b) , 0 (a == b) or 1 (a > b), so we can\'t just pass the provided `fn` variable into `Array.swap()`\n\n# Approach\nCreate a new swap function using `fn` in a closure, and then pass that to the prototype swap method.\n  It would also be possible to just pass this as an anonymous function directly into arr.sort.\n\n# Complexity\n- Time and Space complexity:\n   I couldn\'t find the documented complexity for `Array.Prototype.sort()`, but I assume its using some variation on the quicksort algorithm which would make it `O(n log n)` for time complexity and `O(log n)` for space complexity.\n\n\n# Code\n```\n/**\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nconst sortBy = function(arr, fn) {\n    function swap(a, b) {\n        return (fn(a) < fn(b)) ? -1 : 1\n    }\n\n    return arr.sort(swap)\n};\n```\n\n# VERSION 2\n Here I decided to try implementing my own sort algorithm for practice.  Bubble Sort is too slow for some of the required test cases and will time out, so here I implemented my own QuickSort.  With several runs of this compared to the `Array.sort()` method above, the results were comparable.  There was enough variablility in the test runs results that neither had a clear advantage, but I would give this version a slight time advantage, while version 1 seemed to have a slight memory advantage.\n\n\n```\n/**\n * @param {Array} arr\n * @param {Function} fn\n * @return {Array}\n */\nconst sortBy = function(arr, fn) {\n    // We don\'t need to pass arr as a parameter to each function.\n    function swap(i, j) {\n        [arr[i], arr[j]] = [arr[j], arr[i]]\n    }\n    \n    function partition(start, end) {\n        const pivot = fn(arr[end]);\n        let i = (start - 1); \n        for (let j = start; j <= end - 1; j++) {\n            if (fn(arr[j]) <= pivot) { \n                swap(++i, j)\n            } \n        } \n        swap(++i, end)\n        return i; \n    }\n\n    function quick_sort(start,  end) { \n        if (start < end) {\n            let pi = partition(start, end); \n            quick_sort(start, pi - 1); \n            quick_sort(pi + 1, end); \n        } \n    }\n\n    quick_sort(0, arr.length-1);\n    return arr\n};\n```\n\n\n
['JavaScript']