I expect below, but
julia> x = [3, 5, 7, 4, 0, 9];
x[Not(end)] is also great choice if we are using
DataFrames.jl, or just
x[(end-1):end] is OK. But maybe
tail are very useful like
last. Is there any reason why the functions are not defined for other collections, for instance, performance issue?
I don’t know about historical reasons, but generalizing this is a little tough. For tuples, they are not allocating - the compiler knows exactly the type of Tuple it will return based on the argument. But to do this for a Vector, you’d either need to make a new container or return a surprise
Edit: one other option is a mutation with
popfirst! … But we already have those functions
last apply generically to iterators.
Base.front is basically the same as
Base.tail might not work as expected for all iterators.
Be very careful with this
Not thing, assuming it comes from InvertedIndices.jl. Its implementation is very inefficient, compare:
# manual indexing, baseline:
julia> @btime $x[begin:end-1]
109.519 ns (1 allocation: 96 bytes)
# Not(): 30x slower!
julia> using InvertedIndices
julia> @btime $x[Not(end)]
2.961 μs (35 allocations: 1.14 KiB)
# there's a readable zero-overhead solution in Accessors:
# @delete x[end]
# @delete last(x)
julia> using Accessors
julia> @btime @delete $x[end]
95.899 ns (1 allocation: 112 bytes)
julia> @btime @delete last($x)
95.795 ns (1 allocation: 112 bytes)
But yeah, anyway a more general
tail in Base would be nice.
last optic seems sorta crazy. What is happening there?
Wow, good to know! Thank you!! But
Not is very convenient … I have a question, do your alternative solution actually changes original
I’ve only seen these methods used commonly for recursive inlined Tuple iteration. If comprehension was type stable for tuples it’d probably be used instead.
No magic, just https://github.com/JuliaObjects/Accessors.jl/blob/master/src/functionlenses.jl#L6 (:
Well, Accessors are also very convenient — but more general and efficient!
No, all Accessors operations create a new object and keep the original one intact.
So, it’s used as
y = @delete last(x)
and not as