Module: Enumerable

Defined in:
lib/enumerable_ext.rb,
lib/abstractivator/enumerable_ext.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.get_default(default, other_side_value) ⇒ Object



42
43
44
# File 'lib/abstractivator/enumerable_ext.rb', line 42

def self.get_default(default, other_side_value)
  proc?(default) ? default.(other_side_value) : default
end

.inner_join(left, right, get_left_key, get_right_key) ⇒ Object



36
37
38
39
40
# File 'lib/abstractivator/enumerable_ext.rb', line 36

def self.inner_join(left, right, get_left_key, get_right_key)
  sentinel = Object.new
  result = self.outer_join(left, right, get_left_key, get_right_key, sentinel, sentinel)
  result.reject { |pair| pair.first == sentinel || pair.last == sentinel }
end

.outer_join(left, right, get_left_key, get_right_key, left_default, right_default) ⇒ Object

joins items from left with items from right based on their keys. get_left,right_key are callables which, given an item, return the item’s key. the defaults are used to form a pair for items which have no match. returns an array of 2-element arrays, each of which is a left/right pair.



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
# File 'lib/abstractivator/enumerable_ext.rb', line 9

def self.outer_join(left, right, get_left_key, get_right_key, left_default, right_default)

  ls = left.hash_map(get_left_key)
  rs = right.hash_map(get_right_key)

  raise 'duplicate left keys' if ls.size < left.size
  raise 'duplicate right keys' if rs.size < right.size

  result = []

  ls.each_pair do |k, l|
    r = rs[k]
    if r
      rs.delete(k)
    else
      r = get_default(right_default, l)
    end
    result.push [l, r]
  end

  rs.each_pair do |_, r|
    result.push [get_default(left_default, r), r]
  end

  result
end

.proc?(x) ⇒ Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/abstractivator/enumerable_ext.rb', line 46

def self.proc?(x)
  x.respond_to?(:call)
end

Instance Method Details

#hash_map(get_key, &get_value) ⇒ Object



50
51
52
# File 'lib/abstractivator/enumerable_ext.rb', line 50

def hash_map(get_key, &get_value)
  Hash[self.map{|x| [get_key.(x), get_value ? get_value.(x) : x]}]
end

#inject_right(*args, &block) ⇒ Object



86
87
88
# File 'lib/abstractivator/enumerable_ext.rb', line 86

def inject_right(*args, &block)
  self.reverse_each.inject(*args, &block) # reverse_each to avoid duplicating the enumerable, when possible
end

#inner_join(right, get_left_key, get_right_key) ⇒ Object



58
59
60
# File 'lib/abstractivator/enumerable_ext.rb', line 58

def inner_join(right, get_left_key, get_right_key)
  Enumerable.inner_join(self, right, get_left_key, get_right_key)
end

#outer_join(right, get_left_key, get_right_key, default_value) ⇒ Object



54
55
56
# File 'lib/abstractivator/enumerable_ext.rb', line 54

def outer_join(right, get_left_key, get_right_key, default_value)
  Enumerable.outer_join(self, right, get_left_key, get_right_key, default_value, default_value)
end

#pad_right(n, value = nil, &block) ⇒ Object



90
91
92
93
# File 'lib/abstractivator/enumerable_ext.rb', line 90

def pad_right(n, value=nil, &block)
  block ||= proc { value }
  self + ([n-self.size, 0].max).times.map(&block)
end

#stable_sort(&compare) ⇒ Object



2
3
4
5
6
7
8
9
10
# File 'lib/enumerable_ext.rb', line 2

def stable_sort(&compare)
  compare = compare || ->(a, b){a <=> b}
  xis = self.each_with_index.map{|x, i| [x, i]}
  sorted = xis.sort do |(a, ai), (b, bi)|
    primary = compare.call(a, b)
    primary != 0 ? primary : (ai <=> bi)
  end
  sorted.map(&:first)
end

#uniq?Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
68
69
# File 'lib/abstractivator/enumerable_ext.rb', line 62

def uniq?
  seen = Set.new
  each_with_index do |x, i|
    seen << (block_given? ? yield(x) : x)
    return false if seen.size < i + 1
  end
  true
end