I am no expert, but how about something like this: function histrange{T<:Number,N}(v::AbstractArray{T,N}, n::Integer) # Shortcut function. t(x) = oftype(T,x) if length(v) == 0 return t(Range(0,1,1)) end lo, hi = minimum(v), maximum(v) if hi == lo step = t(1) else bw = (hi - lo) / n e = t(10)^t(floor(log10(bw))) r = bw / e if r <= 2 step = 2*e elseif r <= 5 step = 5*e else step = 10*e end end start = step*t(ceil(lo/step)-1) Range(start,step,1+iceil((hi - start)/step)) end
Cheers, Daniel. On Thursday, 26 December 2013 07:47:09 UTC-5, Michael Fox wrote: > > It's kind of painful to see codes repeating themselves like this. Here's > one I just ran across in `statistics.jl`. Is there something about the type > or dispatch system that encourages or even requires such repetition? Can > you think of a better idea? > > ## nice-valued ranges for histograms > function histrange{T<:FloatingPoint,N}(v::AbstractArray{T,N}, n::Integer) > if length(v) == 0 > return Range(0.0,1.0,1) > end > lo, hi = minimum(v), maximum(v) > if hi == lo > step = 1.0 > else > bw = (hi - lo) / n > e = 10.0^floor(log10(bw)) > r = bw / e > if r <= 2 > step = 2*e > elseif r <= 5 > step = 5*e > else > step = 10*e > end > end > start = step*(ceil(lo/step)-1) > Range(start,step,1+iceil((hi - start)/step)) > end > > function histrange{T<:Integer,N}(v::AbstractArray{T,N}, n::Integer) > if length(v) == 0 > return Range(0,1,1) > end > lo, hi = minimum(v), maximum(v) > if hi == lo > step = 1 > else > bw = (hi - lo) / n > e = 10^max(0,ifloor(log10(bw))) > r = bw / e > if r <= 1 > step = e > elseif r <= 2 > step = 2*e > elseif r <= 5 > step = 5*e > else > step = 10*e > end > end > start = step*(iceil(lo/step)-1) > Range(start,step,1+iceil((hi - start)/step)) > end > >