Is there a built-in function for the natural length of a segment represented by an iterator?

Well, it’s rather simple, but maybe there is already a built-in function to do calculate this?

natural_length(s) = s[end]-s[begin]

natural_length((1,10))
natural_length((1:10))

It annoying to copy-paste this snippet which is not large enough to bother putting it into a package.

It seems quite specific so I doubt there is a built-in function (I might be wrong though). However, last(x) - first(x) seems short enough and self-explanatory.

1 Like

Well, it’s more or less the same as my function.

Yes (last/first might be a tiny bit more performant). I wanted to point it out in case you disliked the indexing in your function.

1 Like

Or maybe there is something like diameter for sets that can be applied to iterators?

This does not work for all iterators.

julia> g = (i for i in 2:10)
Base.Generator{UnitRange{Int64}, typeof(identity)}(identity, 2:10)

julia> natural_length(x) = x[end] -x[begin]
natural_length (generic function with 1 method)

julia> natural_length(g)
ERROR: MethodError: no method matching lastindex(::Base.Generator{UnitRange{Int64}, typeof(identity)})

Why are you using a range for this though?

How about this:

julia> seg = [1,10]
2-element Vector{Int64}:
  1
 10

julia> only(diff(seg))
9

Huh, yet another difference to first/last; they are defined for more types, including your example.

(Btw. diff, on the other hand, is not defined for tuples.)

1 Like

Even last(a) - first(a) seems wrong to me for a non-sorted iterator. A more general solution would be to use the extrema function:

diameter(itr) = -(reverse(extrema(itr))...)

which is equivalent to the more verbose (but more readable) implementation:

function diameter(itr)
    min, max = extrema(itr)
    return max - min
end

(This requires looping over the entire iterator in general, though for a range there is an optimized extrema method that just looks at the endpoints.)

extrema is quite a useful function (which takes some effort to implement well), and provides strictly more information than diameter. So, I don’t think there is much need for a built-in (or package) function to compute diameter, since computing diameter is a one-liner given extrema.

5 Likes

Some variations of the same idea

diamet(itr) = -(-(extrema(itr)...))

diameter(itr) = [-1 1]*[extrema(itr)...]

3 posts were split to a new topic: Transposes vs 1-row matrices

That’s neat.

Well, length is also a one-liner that “defaults to prod(size(A))”, and it’s ever shorter than -(reverse(extrema(itr))...), yet it’s included into the stdlib.

In some sense, diameter is a length for an iterator’s values rather than the container itself.

Because it’s an extraordinarily common function to call.

diameter as defined here does not seem to be commonly needed. Is there any language that provides such a function in its standard library?

1 Like

If we include Numpy, I think it’s numpy.ptp (“peak to peak”).

Matlab also has Maximum-to-minimum difference - MATLAB peak2peak

1 Like