Skip to content

Instantly share code, notes, and snippets.

@Groxx
Created April 29, 2010 04:53
Show Gist options
  • Save Groxx/383161 to your computer and use it in GitHub Desktop.
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.
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
@epochwolf
Copy link

Got ternaries?:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment