-
Notifications
You must be signed in to change notification settings - Fork 19
flatten shallow by default #9
Comments
I have discussed with others and there seems to be a weak consensus for 1-level-by-default. I was basing the semantics off of what I was familiar with (Ruby) but the arguments in favor of level-1-by-default are strong. Will update. |
any updates so far? I agree with the sense of less work by default and the arg will escalate it to the necessary level if necessary. This would also make flatten similar to flatMap and more intuitive to use both. |
Haven't updated spec text, adding to backlog again due to renewed interest. 1-level deep is the obvious way to go. |
A highly unscientific survey of my cohorts has suggested that:
If the shallow flattening is undesired behavior, then the performance benefit is illusory. If there's only one layer of arrays, then it's the same performance, and if there are more, then it's the wrong outcome. Are we wrong about real-life use cases? |
This may have been closed but I must disagree with this decision. Complete flattening is a common use case, so what value of depth should be used when that's desired; Number.MAX_SAFE_INTEGER? Or does the array have to be traversed to calculate the correct depth; hardly a performant solution. If you want a depth of 1, specify it. At the very least, but hardly ideal, allow a more convenient depth value of 0 or -1 to specify complete flattening. Or provide a flatten_deep() method to do this job. |
If you want infinite flattening, you can pass a Infinity. |
Yes I can (see Number.MAX_SAFE_INT) but isn't it much easier for those who want a depth of 1 to specify 1? And isn't the resulting code semantically clearer? By the way, I don't want "infinite" flattening, just sufficient flattening (instance dependent). For other usage see (Node module): And see "popular" answer for flatten(arr) at: amongst others. Just seems this proposal is making a common use case unnecessarily complicated in order to make a simple use case even simpler and for no particular reason IMO. |
sufficient flattening depends on your use case; you might want to flatten an array like |
You’re still answering @ridgeworks’ “how do I do it” question from two comments ago, dodging the follow up “common case” point. I for one understand that |
(Followup to pre-apologize for “dodging”, which suggests intent. I should have said “missing”.) |
@dcporter fair :-) I think that "Common case" is obviously quite subjective, though - but the OP to me quite convincingly indicates that the default should be 1. |
I must disagree that 1 is the obviously common case. I think it's quite a common case to dynamically build a nested array structure, e.g., from a parser, and flatten it to some output. I'm not arguing it's the only case; just that when you want it, providing some arbitrarily large integer value seems contrived to say the least. Some more existing art in the form of JS libraries (they're not hard to find) that at least recognizes it's a common situation: underscore.js - flatten() defaults to deep, but takes an extra boolean parameter for shallow (1 level) ramda.js - flatten() flattens deep, use unnest() for shallow(?) loadash - flatten() flattens 1 level but flattenDeep() also provided collections.js - flatten() flattens deep (I think) |
You shouldn't provide "some arbitrarily large integer value". You should provide That doesn't seem contrived to me. |
I concede that Or maybe I'm missing something about the rationale behind this proposal. A function that does a shallow flatten using the "slightly quirky" (IMO) behaviour of Array.concat is pretty simple to write:
although to be fair, deep flatten isn't much more complicated:
So maybe it's about performance - all those intermediate
Can an implementation based on the Unfortunately I don't think the deep flatten case has a similar performant solution - correct me if I'm wrong. And it's also recursive so, absent TRO, it can get quite expensive in relative terms. So it could really benefit from an optimized built-in, although it seems to have lower priority in this discussion. Apologies if this comes off as a rant. It's just the default we're talking about and it's not a huge deal; more of a missed opportunity (IMO). |
Sorry, I mixed my metaphors in the previous post. Deep flatten should be:
|
In light of the MooTools debacle, can we consider reopening this? |
For what it’s worth, if @timwienk’s comment in mootools/mootools-core#2797 (comment) is correct, then
If this is true, then |
It turns out the difference in default depth is not the issue with MooTools; see here. So I don't think this needs to be revisited. |
😢 |
I would be in favour of deep flattening, too. Seems more intuitive. |
@bakkot Thanks for your detailed investigation into the issue with MooTools. I'd give a 😱 react if I could. Would we solve the compatibility problem if we made |
Enumerable methods on Array.prototype cause for-in loops to get confused, so unless we add |
Shouldn't anyone who complaints this will break MooTools be making an issue with MooTools https://github.com/mootools/mootools-core rather than asking language to accommodate their library choices? If they are developers... that's kinda what we get paid for to stay on top of the changes. Right? |
@domenic Oh, right, of course. Never mind. |
The thing that I find confusing about a default depth of 1 is that the name |
@jgaskins I quite like unwrap for the one layer use case. |
I would definitely get behind “flatten” defaulting to Infinity and “unwrap” defaulting to 1, or either one if we didn’t want to double the surface area. |
Hey Brian. I dig these proposals!
I think
Array#flatten
should be shallow by default because it makes sense to do less work by default, it aligns with existing APIs like the DOMNode#cloneNode
which is shallow by default, and it would align with the existing ES3 pattern of usingArray#concat
for a shallow flatten. Shallow by default would also align withflatMap
too.The text was updated successfully, but these errors were encountered: