Reputation: 15336
Is it possible to write multiple function calls as a chain?
sum(
map(parseIgFloat,
map((row) -> row.PL_Amount,
filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In",
collect(ts)
)
)
)
)
Turn it into something like:
ts
|> collect
|> filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In")
|> map((row) -> row.PL_Amount)
|> map(parseIgFloat)
|> sum
Upvotes: 3
Views: 1991
Reputation: 12654
I would probably write it like this:
sum(row -> parseIgFloat(row.PL_Amount),
filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In",
ts)
)
If and when underscore currying comes about (https://github.com/JuliaLang/julia/pull/24990) you could simplify it like this:
sum(parseIgFloat(_.PL_Amount)),
filter(!ismissing(_.Summary) && _.Summary == "Cash In", # actually not sure if this line would work
ts)
)
At that point chaining might also become more convenient.
By the way: don't use collect
unless you somehow really have to.
Upvotes: 1
Reputation: 22215
In general, what you ask is difficult, since whatever construct you came up with, you would have to guarantee the order of arguments as passed is the order expected by the function, so there is no general enough method to allow you to do this without defining explicit types and operations for it.
However, with respect to map
and filter
specifically, it is trivial to create 'curried' versions of these functions and apply chaining to them. E.g.
# Create curried versions of map and filter for use in 'chaining'
import Base.map; function map(f); return L -> map(f,L); end;
import Base.filter; function filter(f); return L -> filter(f,L); end;
f = x -> x ^ 2;
ts = range(1, stop=10);
( ts
|> collect
|> map(f) # square the collection
|> filter(iseven) # keep only even results
|> sum
)
Output:
220
PS2: Also note that, the |>
operator is a valid target for broadcasting, like any function. Therefore |> map(f)
above could also have been written more simply as .|> f
instead.
Upvotes: 3
Reputation: 15336
After searching, this seems to be the best option available
ts |>
collect |>
(list -> filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", list)) |>
(list -> map((row) -> row.PL_Amount, list)) |>
(list -> map(parseIgFloat, list)) |>
sum
or with the Pipe
package with the macros
@pipe ts |>
collect |>
filter((row) -> !ismissing(row.Summary) && row.Summary == "Cash In", _) |>
map((row) -> row.PL_Amount, _) |>
map(parseIgFloat, _) |>
sum
Upvotes: 4