(no title)
heydenberk | 4 years ago
[1, 2, 3, 4, 5].filter(n => n % 2 === 1).map(n => n * 2)
You can do: [1, 2, 3, 4, 5].flatMap(n => n % 2 === 1 ? [n * 2] : [])
Again, this is a contrived example, but I think it's interesting since the generality is not obvious (to me)
Vanit|4 years ago
> Note, however, that this is inefficient and should be avoided for large arrays: in each iteration, it creates a new temporary array that must be garbage-collected, and it copies elements from the current accumulator array into a new array instead of just adding the new elements to the existing array.
heydenberk|4 years ago
hildjj|4 years ago
That note is misleading.
jasonkillian|4 years ago
In TypeScript, you might have an array of multiple types (e.g. `Array<A | B>`), and use a `filter` call to only keep the `A`s. However, in many situations TypeScript can't figure this out and the resulting array type is still `Array<A | B>`. However, when you just use `flatMap` to do nothing more than filtering in the same way, TypeScript can determine that the resulting type is just `Array<A>`. It's a bit unfortunate really - `filter` is faster and more readable, but the ergonomics of `flatMap` type-wise are so much nicer! Just some interesting trivia.
[0]: https://github.com/microsoft/TypeScript/issues/16069#issueco...
amitport|4 years ago
You could potentially add a syntax for type guards function types, then add a signature to filter that accepts a type guard and returns an array of the guarded types.
Shouldn't be too much of a stretch given that we have type guards.
The syntax is a bit annoying... should be something like filter<A, B>(cb: A => A is B)
:/
niek_pas|4 years ago
lalaithion|4 years ago
nefitty|4 years ago
frozenlettuce|4 years ago
nothing, but they do have some relationship to 0, "" and Promise.resolve() - the array is handling the logic that will make the results be combined, not the doubling part
hajile|4 years ago
dwohnitmok|4 years ago
You do have to make sure that your implementation of list is extremely efficient on zero and one element lists (ideally it generates no garbage at all in those cases) otherwise as other commentators have pointed out you'll have a lot of GC pressure.
And even though the transducer itself is `x -> List(x)` note that the `List` is only produced as an intermediate step and doesn't need to exist in the final product. You could apply a `x -> List(x)` to a generator for example and just "absorb" the list back into the resulting generator.
ljm|4 years ago
Or to put it another way, if I reviewed code where someone used flatMap for anything other than lists of lists I'd be likely to suggest filter/map or reduce or some other convenient equivalent depending on the purpose of the code.
Something like Ruby's filter_map[0] would do the job, although not with this particular example (because 0 is truthy in Ruby).
[0] https://ruby-doc.org/core-3.1.0/Enumerable.html#method-i-fil...
vanderZwan|4 years ago
kaba0|4 years ago
newlisp|4 years ago
femto113|4 years ago
nesarkvechnep|4 years ago
ReleaseCandidat|4 years ago
[1, 2, 3, 4, 5].reduce((acc, n) => n % 2 === 1 ? acc.push(2*n) : acc, [])
christophilus|4 years ago
eyelidlessness|4 years ago
pwdisswordfish9|4 years ago
unknown|4 years ago
[deleted]