Bug: `join` on ArrayLikeSequence from `values` of ObjectLikeSequence does not include delimiter.
AaronJRubin opened this issue · comments
console.log(Lazy({lat: 57.278, lng: 23.8}).values().join())
Output:
57.27823.8
Expected output:
57.278,23.8
The following work-around produces the expected output:
console.log(Lazy({lat: 57.278, lng: 23.8}).values().toArray().join())
OK, so I'm pretty sure that the problem is that values()
on an ObjectLikeSequence returned a MappedObjectLikeSequence, the each
method (which backs reduce
, which backs join
) of which just delegates to the each
method of ObjectLikeSequence. In the each
method of ObjectLikeSequence, the i
that is passed to the callback is the key, rather than the index, and the callback that is passed to reduce
in the implementation of join
expects a numerical index to determine when the delimiter is necessary.
`Sequence.prototype.join = function join(delimiter) {
delimiter = typeof delimiter === "string" ? delimiter : ",";
return this.reduce(function(str, e, i) {
if (i > 0) {
str += delimiter;
}
return str + e;
}, "");
};`
Whew! Took me a while to track that down.
Here's a simple solution - just add the delimiter every time, and then cut off the final character before returning.
(Side note - do we like the fact that the implementation of join
has n^2 performance? Perhaps there's some optimization in V8 that makes this better than it looks?)
Ahhh, apparently String concatenation in modern browsers is just as fast as using Array.join(), because optimizations. https://jsperf.com/string-concat-without-sringbuilder/5.
Yes, string concatenation being as fast as Array.join()
is a fun little discovery everybody makes at one point or another :)
I actually wrote a blog post about this about a million years ago.