Created
April 29, 2010 04:53
-
-
Save Groxx/383161 to your computer and use it in GitHub Desktop.
Grab a portion of an array where the item number / index number has the same left-most digits as are passed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Array | |
# Returns a portion of an array in which the left-most numbers | |
# match the prefix. If 0 (or less) is passed, matches all | |
# single-digit numbers (same as [0..8]). | |
# | |
# === Warning | |
# This deals with the n-th items, <i><b>NOT</b></i> the n-th | |
# <i>indexes</i> (ie, it's 1 based, not 0 based), because it | |
# serves my needs currently, and allows zero to match all | |
# single-digit items. To get the indexes of the returned | |
# items, just subtract one. | |
# | |
# === Example | |
# * 0 => [1, 2, 3, 4, 5, 6, 7, 8, 9] | |
# * 1 => [1, 10, 11, 12, 13, ..., 100, ..., 157, ..., 199, etc.] | |
# * 12 => [12, 120, 121, 122, 123, ..., 1200, ..., 1257, ..., 1299, etc.] | |
# | |
# Non-optimal, but highly effective, and more readable. And | |
# though it's not optimal, it is very fast due to Ruby's | |
# efficient <tt><<</tt> array appending operation. This will | |
# also preserve any multi-dimensional array structure, where | |
# a more optimal solution may not. | |
# | |
# Optimal method unknown, will need benchmarking to determine, | |
# and that's not really necessary for the scale I'm working at. | |
def prefix(prefix) | |
return self[0..8] if prefix < 1 | |
result = [] | |
scale = 0 | |
while true do | |
unless self[((left=prefix*10*scale-1)==-1 ? (scale==0 ? prefix-1 : prefix) : left)..((right=prefix*10*scale+(10*scale-1))==-1 ? prefix-1 : (scale > 0 ? right-1 : right))].nil? | |
self[((left=prefix*10*scale-1)==-1 ? (scale==0 ? prefix-1 : prefix) : left)..((right=prefix*10*scale+(10*scale-1))==-1 ? prefix-1 : (scale > 0 ? right-1 : right))].each do |item| | |
result << item | |
end | |
else | |
break | |
end | |
scale = scale * 10 | |
scale = 1 if scale == 0 | |
end | |
return result | |
end | |
# Returns a portion of an array in which the left-most index | |
# digits match the prefix. If a negative number is passed, | |
# matches all single-digit indexes (same as [0..9]). | |
# | |
# === Warning | |
# This deals with the n-th indexes, <i><b>NOT</b></i> the n-th | |
# <i>items</i>. | |
# | |
# === Example | |
# * -1 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
# * 0 => [0] | |
# * 1 => [1, 10, 11, 12, 13, ..., 100, ..., 157, ..., 199, etc.] | |
# * 12 => [12, 120, 121, 122, 123, ..., 1200, ..., 1257, ..., 1299, etc.] | |
# | |
# Non-optimal, but highly effective, and more readable. And | |
# though it's not optimal, it is very fast due to Ruby's | |
# efficient <tt><<</tt> array appending operation. This will | |
# also preserve any multi-dimensional array structure, where | |
# a more optimal solution may not. | |
# | |
# Optimal method unknown, will need benchmarking to determine, | |
# and that's not really necessary for the scale I'm working at. | |
def prefix_index(prefix) | |
return self[0] if prefix == 0 | |
return self[0..9] if prefix < 0 | |
result = [] | |
scale = 0 | |
while true do | |
unless self[((left=prefix*10*scale-1)==-1 ? prefix : left+1)..((right=prefix*10*scale+(10*scale-1))==-1 ? prefix : right)].nil? | |
self[((left=prefix*10*scale-1)==-1 ? prefix : left+1)..((right=prefix*10*scale+(10*scale-1))==-1 ? prefix : right)].each do |item| | |
result << item | |
end | |
else | |
break | |
end | |
scale = scale * 10 | |
scale = 1 if scale == 0 | |
end | |
return result | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Got ternaries?: