Proposal: Static sort method on Array

# Rob Ede (6 years ago)

I don't like the fact the only way to sort is in-place with Array#sort and I can't be the first to feel this way or wonder why there isn't a built-in solution.

Obviously, searching "javascript array.sort" doesn't produce any helpful results to see if someone has suggested this before since all the results relate to Array#sort.

I'm considering creating a proposal to add an Array.sort() method that takes an array and returns a new array. It seems like such a simple addition that would remove the need to import lodash, write a helper function or use a slightly less clear and possibly slower technique like [...arr].sort().

# Claude Pache (6 years ago)

Le 7 avr. 2018 à 21:59, Rob Ede <robjtede at icloud.com> a écrit :

I don't like the fact the only way to sort is in-place with Array#sort and I can't be the first to feel this way or wonder why there isn't a built-in solution.

Obviously, searching "javascript array.sort" doesn't produce any helpful results to see if someone has suggested this before since all the results relate to Array#sort.

I'm considering creating a proposal to add an Array.sort() method that takes an array and returns a new array. It seems like such a simple addition that would remove the need to import lodash, write a helper function or use a slightly less clear and possibly slower technique like [...arr].sort().

Array.from (or indeed [...arr]) is a generic built-in way to create a new array, and is fine to use in every occasion where you need a copy. (Before ES6, there was already arr.slice(0).) I don’t think it is appropriate to have an additional way to copy arrays for this specific case (it would be one more thing to learn).

# C. Scott Ananian (6 years ago)

To be super explicit: given an array 'a', then: Array.from(a).sort() will return you a sorted clone. That works even if a has an iterator or is an array-like object. That's just seven characters longer than Array.sort(a), which is what you seem to be proposing.

To be sure, I don't think the wider world (ie, a naive Google search) knows the full wonders of Array.from yet. I particularly like using it on strings...

# T.J. Crowder (6 years ago)

On Sat, Apr 7, 2018 at 8:59 PM, Rob Ede <robjtede at icloud.com> wrote:

...I'm considering creating a proposal to add an Array.sort() method that takes an array and returns a new array...

That would be:

let newArray = originalArray.slice().sort();
// or
let newArray = Array.from(originalArray).sort();
// or
let newArray = [...originalArray].sort();

I don't know that we need a new static for it. Unless the motivation is to allow insertion sort or other sort algorithms that work best when creating a new array as a result? But if we assume Array.prototype.sort already uses quicksort or mergesort or similar, I'm not seeing much reason to add a new static to allow insertsion sort or similar...

Can you expand on use cases and why the above aren't sufficient?

-- T.J. Crowder

# Isiah Meadows (6 years ago)

When I need a non-in-place sort, I just do array.slice().sort(). It's pretty easy, and it still chains. (In my experience, it's rarely necessary considering most chaining methods like .map and .filter already return new instances.)

Isiah Meadows me at isiahmeadows.com

Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com

# Naveen Chawla (6 years ago)

slice() is better than Array.from() if you already have an array because you can chain it with the other Array.prototype methods.

Good point about not needing it after you've done a map/filter/concat or whatever, since you already have a new array.

However I agree with the thrust of a proposal that produces a new array from sort instead of in-place, at least from when sort was being introduced. I have made bugs on this presumption with sort(), until I learned it is in-place.

However, since sort() exists as it is now, it could be too confusing to have 2 sorts in JavaScript. If this is the case, we may have to accept this as a JavaScript language mistake in hindsight that we have to work around using slice(), specific to sort (but not the other Array.prototype methods).

But, if it's not too confusing, then I would have no problem with e.g.:

Array.prototype.sortedShallowClone

being introduced to the language.

# kai zhu (6 years ago)

if you want to adhere to the python/jslint philosophy of “there should be one and preferably only one common design-pattern to do it”, then array.from is the most suitable candidate for copying/coercing lists. it can generalise to common pseudo-lists like function-arguments and frontend-query-selectors, which array.slice cannot as shown in these real world examples [1] [2]:

/*
 * coerce/copy frontend query-selector pseudo-list to list
 */

// disable <script> tag

Array.from(
    document.querySelectorAll('script')
).forEach(function (element) {
    element.outerHTML = '<script></script>';
});
/*
 * coerce/copy function-argument pseudo-list to list
 */

task.onDone = function () {
    ...
    // preserve error.message and error.stack
    task.result = JSON.stringify(Array.from(arguments)
        .map(function (element) {
            if (element && element.stack) {
                element = local.objectSetDefault(local.jsonCopy(element), {
                    message: element.message,
                    name: element.name,
                    stack: element.stack
                });
            }
            return element;
        }));

[1] kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L2781, kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L2781 [2] kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L5844, kaizhu256/node-utility2/blob/2018.1.13/lib.utility2.js#L5844