Martin said:
irb(main):005:0> ("aa".."b1").to_a
["aa".."zz" elided]
Then said:
Exactly.
And the same holds true of many a sequence, like even numbers. Now how can membership be optimized in a custom manner?
Maybe I'm about to say something silly (by not being up-to speed) but
why on earth could anyone consider the output from the above one-liner
to be sane? Not only is upper bound exceeded (under any sensible notion
of comparison) but many intermediate values are missing for example "b!"
and "a~" as well as more esoteric strings with control characters such
as "b\0" and all strings with capital letters in them?
To make matters worse, even if we accept that ranges have a peculiar
semantics over strings, they are inconsistent.
irb(main):001:0> ("aa".."b1")==="zz"
=> false
irb(main):002:0> ("aa".."b1").to_a.include? "zz"
=> true
The max method also behaves in a very counter intuitive way without
converting to an array:
irb(main):003:0> ("A".."d").max
=> "Z"
Establishing set membership is something for which (in other languages)
I've long had an active interest - which brings me to comment on the
even numbers question. A really powerful resolution of range would
support "modifiers":
Projection- Applying a function to each element
Selection- Filtering values which do not exist
Intersection- Retaining only values present in both
Union - Retaining values present in either
Minus - Retaining values present in the first but not the second.
It is interesting to note that it is possible to efficiently compute
membership (without enumerating all the possible values) unless
Projection is applied. If projection is applied then it is necessary
that the projection function can be inverted - which can't be done in
the general case. So, given an appropriate implementation of efficient
- the following generate the odd numbers below n.
efficient(0..n).filter { |x| x%2==0 }
efficient(0..(n/2)).project { |x| x=x*2 }
efficient(0..n).minus efficient(0..n).filter { |x| x%2==1 }
... and many, many more possibilities...
For each of these (except project, assuming no-one supplies the
hand-verified inverse to the supplied function) there are efficient
[i.e. far better than O(n)] ways to establish membership.
Does anyone not claim that ranges are broken with respect to strings?