Fwd: Feature proposal
On Wed, Jul 18, 2018 at 5:44 PM, Cyril Auburtin <cyril.auburtin at gmail.com>
wrote:
sorry you get 1, and need again to subtract the array length, `arr.length -1
- 1` to get the final result 3
So you can't just use the passed-in third argument, and need:
let a = [7, 4, 6, 7, 12];
console.log(a.length - 1 - a.findIndex((_, i) => isPrime(a[a.length-1-i])));
Strikes me as a reasonable argument for adding findLastIndex
. ;-) (And
perhaps findLast
, since the same trick with find
just won't work at
all.)
Prior art (looking for instance at the libs that inspired the array additions in ES5 and ES2015):
- Lodash implements both
findLastIndex
andfindLast
). - Underscore, PrototypeJS, and MooTools don't as far as I can see from the docs.
-- T.J. Crowder
Is strikes me that every single Array method that takes an iteratee function (signature (value, index, array)) should be able to iterate through the array in reverse, in a standardised way.
At the moment, we have:
- every
- filter
- find
- findIndex
- forEach
- indexOf / lastIndexOf
- map
- reduce / reduceRight
- some
which is not very consistent at all. Perhaps we could add an iterOrder
method that changes the way the array is iterated through?
I propose it could take 1 parameter:
- If -1 is passed in, the array is iterated through in reverse.
- If 1,0 or undefined is passed through, the array is iterated through normally.
- If an array of numbers is passed through, these represent the indexes in the order they will be processed.
- Any illegible indexes in the passed-in array will be ignored
- Any eligible indexes not given will be ignored
- If a generator function is passed in, it should take the array (or a length value) and spit out indexes.
- If a non-generator function is passed in, it should spit out an array of indexes, which will be used as-per arrays being passed in
Whether that iterOrder is reset after an iteration could go either way. I'd suggest it probably should, with an option to persist.
Example:
let arr = [ 8,4,7,3 ];
arr.iterOrder().map(x => x) === arr
arr.iterOrder(-1).map(x => x) === arr.reverse() === [ 3,7,4,8 ]
arr.iterOrder([ 2,1 ]).map(x => x) === [ 7,4 ]
// haven't got time to give function arg examples, but randomisers would be
fairly trivial
// original indexes are preserved during iteration:
arr.iterOrder(-1).forEach((val, i) => console.log(val, i))
// > 3, 3
// > 7, 2
// > 4, 1
// > 8, 0
This is a messy first-pass at the problem, and I can already see potential issues, but it would at least standardise and generalise the problem
On Wed, Jul 18, 2018 at 6:31 PM, Michael Luder-Rosefield < rosyatrandom at gmail.com> wrote:
Is strikes me that every single Array method that takes an iteratee
function
(signature (value, index, array)) should be able to iterate through the array in reverse, in a standardised way.
Yeah, I had a similar thought. We're talking arrays, not generic iterables, after all.
My thought was some kind of reversed view of the array, something like this:
const reversedView = array => new Proxy(array, {
get(target, prop, receiver) {
if (isArrayIndex(prop)) {
prop = target.length - 1 - prop;
}
return Reflect.get(target, prop, receiver);
}
});
...but thought-through, tested, and efficient (which the above Is Not -- it does work in a basic couple of checks, but I'm running out the door and wouldn't be surprised if there are edge cases not handled: jsfiddle.net/80se3xqj). Then my mind sort of wanders off wanting to generalize this concept of a view on an array... :-)
Amusingly, this doesn't help at all with the original request here:
findLastIndex
(because it would return the index in the reversed view,
not the original array). But it does with forEach
, find
, some
, etc.:
const objects = [
{id: 1, type: 1},
{id: 2, type: 2},
{id: 3, type: 2},
{id: 4, type: 3}
];
console.log(reversedView(objects).find(o => o.type === 2));
Finds {id: 3, type: 2}
.
-- T.J. Crowder
On Wed, Jul 18, 2018 at 5:31 PM, Michael Luder-Rosefield <rosyatrandom at gmail.com> wrote:
At the moment, we have:
every filter find findIndex forEach indexOf / lastIndexOf map reduce / reduceRight some
which is not very consistent at all. Perhaps we could add an
iterOrder
method that changes the way the array is iterated through?
Stupid question, but why are some of these methods implemented on
String, Array, TypedArray, Map and Set, while all of them are
Iteratable?
If we were to add all these methods on Iteratable, then one could add
a reverse
generator property on Iteratable.
Iteratable.prototype.reverse = function* reverse() { … }; foo.reverse().forEach( e => console.log(e) )
Though, this implies that all these objects implement the Iteratable prototype, and I am not sure what impact this might have on the Web.
Sorry, I got lost.
I partially agree with Michael Luder-Rosefield.
The main reason I started this thread is consistency. Because I can't get
the logic behind what Michael listed above.
I don't think I can support the idea of
iterOrder
. Looks like a try to create silver bullet and I don't think
it's a handy way to perform these examples.
Looks more universal than handy to me.
I like the idea to expand this proposal for
find
method as well.
Thanks.
P. S. This is my first proposal, so I apologies for bad formatting and forwarding.
On Wed, Jul 18, 2018 at 2:06 PM Nicolas B. Pierron < nicolas.b.pierron at mozilla.com> wrote:
On Wed, Jul 18, 2018 at 5:31 PM, Michael Luder-Rosefield <rosyatrandom at gmail.com> wrote:
At the moment, we have:
every filter find findIndex forEach indexOf / lastIndexOf map reduce / reduceRight some
which is not very consistent at all. Perhaps we could add an
iterOrder
method that changes the way the array is iterated through?Stupid question, but why are some of these methods implemented on String, Array, TypedArray, Map and Set, while all of them are Iteratable?
String is different from the others. The String index methods deal with a contiguous subsequence of the sequence, not the index of an element in the sequence.
If we were to add all these methods on Iteratable, then one could add a
reverse
generator property on Iteratable.
Reverse is problematic on String. The index of a codepoint can't be subtracted from String.length since length is not the count of codepoints.
Just a note: there does exist a destructive method to do this:
Array.prototype.reverse()
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse
Isiah Meadows me at isiahmeadows.com, www.isiahmeadows.com
Above we was talking about this. consistency and handy using -- two main reasons for this proposal.
reverse
will also mutate my array, cause of in-place implementation.
You can find workaround for many existing methods, but it's not handy to my mind.
What about this alternate proposal:
(I've got a myriad of other related stuff there, too.)
On Thu, Jul 19, 2018 at 9:49 AM, Isiah Meadows <isiahmeadows at gmail.com> wrote:
What about this alternate proposal:
Great minds: esdiscuss.org/topic/fwd-feature-proposal#content-5 ;-)
-- T.J. Crowder
This array view thing is very close to what I had in mind, and seems to suggest to a lot of interesting possibilities.
What strikes me as the two most significant are:
- again, 'reversed' is just one alternative iteration order through, though almost certainly the most useful
- others I can think of could be 'even/odd indexes', 'random shuffle', 'iterate-until /while-condition', and filter equivalents
- as well as the view defining the iteration order, it could define the
computed value
- this would be basically a map where the value isn't computed until accessed; caching behaviour could be user
I'd rather keep it restricted to very simple, context-free things like a reverse subtract or single add, with only a few bits of data necessary. Anything more is going to be a perf concern because you can't avoid visible side effects.
Cool, gonna read it out.
First impression -- it can make methods more complex and usage will be
different between find
, findlastIndex
etc., if we want to use something
like reverseView
.
2018-07-19 11:56 GMT+03:00 T.J. Crowder <tj.crowder at farsightsoftware.com>:
On Wed, Jul 18, 2018 at 6:43 PM, Mike Samuel <mikesamuel at gmail.com> wrote:
On Wed, Jul 18, 2018 at 2:06 PM Nicolas B. Pierron <nicolas.b.pierron at mozilla.com> wrote:
Stupid question, but why are some of these methods implemented on String, Array, TypedArray, Map and Set, while all of them are Iteratable?
String is different from the others. The String index methods deal with a contiguous subsequence of the sequence, not the index of an element in the sequence.
I am not sure why this would prevent us from adding an Iteratable
object with common properties. Iteratable.prototype.foo
can exist
at the same time as String.prototype.foo
, and calling the foo
property on a String will result in calling String.prototype.foo
.
Also one could implement a naïve/default implementation of
reverseOrder
which allocates a temporary array for object which have
no random accesses capabilities.
Iteratable.prototype.reverseOrder = function* () {
for (let e of [...this].reverse())
yield e;
}
If we were to add all these methods on Iteratable, then one could add a
reverse
generator property on Iteratable.Reverse is problematic on String. The index of a codepoint can't be subtracted from String.length since length is not the count of codepoints.
Don't take me wrong, I was not suggesting to add a reverse
property.
I was suggesting to add the Iteratable object in the prototype chain
such that someone can implement extra property on the Iteratable /
Iteratable.prototype object.
Among list of nice Iteratable property that one might add, and which might not be part of the standard are things like: chain, take, skip, takeWhile, skipWhile, repeat, zip, enumerate, range, stepBy, …
Another option would be to just add a property named iter
which
returns an Iteratable object.
On Thu, Jul 19, 2018 at 8:54 AM Nicolas B. Pierron < nicolas.b.pierron at mozilla.com> wrote:
On Wed, Jul 18, 2018 at 6:43 PM, Mike Samuel <mikesamuel at gmail.com> wrote:
Reverse is problematic on String. The index of a codepoint can't be subtracted from String.length since length is not the count of codepoints.
Don't take me wrong, I was not suggesting to add a
reverse
property. I was suggesting to add the Iteratable object in the prototype chain such that someone can implement extra property on the Iteratable / Iteratable.prototype object.
My mistake. I assumed a goal was to allow implementing a generic findLastIndex in terms of find and reverse iterators.
On Thu, Jul 19, 2018 at 12:53 PM, Nicolas B. Pierron <nicolas.b.pierron at mozilla.com> wrote:
On Wed, Jul 18, 2018 at 2:06 PM Nicolas B. Pierron <nicolas.b.pierron at mozilla.com> wrote:
Stupid question, but why are some of these methods implemented on String, Array, TypedArray, Map and Set, while all of them are Iteratable?
Among list of nice Iteratable property that one might add, and which might not be part of the standard are things like: chain, take, skip, takeWhile, skipWhile, repeat, zip, enumerate, range, stepBy, …
Apparently this already exists as a JS library: fitzgen.github.io/wu.js
I'm not a fan of the "Iteratable" object - it doesn't align with the corresponding existing concept of "iterables", and the iterable protocol is just an interface - there's no named object that corresponds to that type.
What we really need is that pipeline operator to finally get figured out: tc39/proposal-pipeline-operator
That wil address the primary need for things like these, without running you into issues of namespace collision.
Isiah Meadows me at isiahmeadows.com, www.isiahmeadows.com
---------- Forwarded message ---------- From: Dmitry Shulgin <shulhindvst at gmail.com>
Date: 2018-07-05 10:36 GMT+03:00 Subject: Feature proposal To: es-discuss at mozilla.org
I came across a task of finding an index of the last element in array that satisfies the condition, so i reversed array and found it by *findIndex * function. I was thinking: Why do we have findIndex` method, but no findLastIndex? It seems logical to follow [index|lastIndex]Of pair, doesn't it? Reversing array in this case seems too complicated to me.
So, i would like to suggest new method like Array.prototype.findLastIndex()
Example:
function isPrime(element, index, array) { var start = 2; while (start <= Math.sqrt(element)) { if (element % start++ < 1) { return false; } } return element > 1; }
console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found console.log([7, 4, 6, 7, 12].findIndexLast(isPrime)); // 3
Would be glad to implement, if it makes sense.
Thx for replies.
P.S. Small issue on GitHub was closed due to offtop (not an issue, as i understand). tc39/ecma262#1253