Proposal: Static sort method on Array
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).
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...
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
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
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 sort
s 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.
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
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()
.