Module: Iron::Lexorank::Utils
- Included in:
- Rankable::ClassMethods, Rankable::InstanceMethods
- Defined in:
- lib/iron/lexorank/utils.rb
Constant Summary collapse
Instance Method Summary collapse
- #get_char(string, index, default_char) ⇒ Object
- #mid(prev, after) ⇒ Object
- #optimal_rank_numeric_interval_for(items_count) ⇒ Object
- #to_rank(number) ⇒ Object
- #value_between(before_, after_) ⇒ Object
Instance Method Details
#get_char(string, index, default_char) ⇒ Object
54 55 56 |
# File 'lib/iron/lexorank/utils.rb', line 54 def get_char(string, index, default_char) index >= string.length ? default_char : string[index] end |
#mid(prev, after) ⇒ Object
49 50 51 52 |
# File 'lib/iron/lexorank/utils.rb', line 49 def mid(prev, after) middle_ascii = ((prev.ord + after.ord) / 2).round middle_ascii.chr end |
#optimal_rank_numeric_interval_for(items_count) ⇒ Object
70 71 72 73 74 75 76 |
# File 'lib/iron/lexorank/utils.rb', line 70 def optimal_rank_numeric_interval_for(items_count) i = 1 while items_count >= BASE ** i i += 1 end (BASE ** i) / (items_count + 1) end |
#to_rank(number) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/iron/lexorank/utils.rb', line 58 def to_rank(number) return MIN_CHAR if number.zero? result = "" while number > 0 remainder = number % BASE number /= BASE result = (MIN_CHAR.ord + remainder).chr + result end result end |
#value_between(before_, after_) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/iron/lexorank/utils.rb', line 6 def value_between(before_, after_) before = before_ || MIN_CHAR after = after_ || MAX_CHAR rank = "" (before.length + after.length).times do |i| prev_char = get_char(before, i, MIN_CHAR) after_char = get_char(after, i, MAX_CHAR) if prev_char == after_char rank += prev_char next end mid_char = mid(prev_char, after_char) if mid_char == prev_char || mid_char == after_char rank += prev_char next end rank += mid_char break end # Problem: If we try to get a rank before the character '0' or after 'z' the algorithm would return the same char # This first of all breaks a possible unique constraint and of course makes no sense when ordering the items. # # Thoughts: I think this issue will never happen with the Lexorank::Rankable module # Why? Let's look at '0' as a rank: # Because the algorithm always chooses the char in between two other chars, '0' can only happen when before is nil and after is '1' # In this case the algorithm will return '0U' though. This means there will never be an item with rank '0' which is why this condition # should never equal to true. # # Please report if you have another opinion about that or if you reached the exception! (of course you can force it by using `value_between(nil, '0')`) if rank >= after raise Lexorank::Exceptions::InvalidRankError, "This rank should not be achievable using the Lexorank::Rankable module! " \ "The supplied ranks were #{before_.inspect} and #{after_.inspect}." end rank end |