Module: Enumerable

Defined in:
lib/quality_extensions/enumerable/every.rb,
lib/quality_extensions/symbol/match.rb,
lib/quality_extensions/color/gradiate.rb,
lib/quality_extensions/enumerable/select_while.rb,
lib/quality_extensions/enumerable/map_with_index.rb

Overview

Author

vinterbleg <snippets.dzone.com/posts/show/5119>, Tyler Rick

Copyright

Copyright © Its authors.

License

Ruby License

Submit to Facets?

Yes. facets/enumerable/collect.rb only has non-in-place version (map_with_index).

Developer notes
Changes

++

Instance Method Summary collapse

Instance Method Details

#every(n) ⇒ Object

Yields every nth object (if invoked with a block), or returns an array of every nth object.

every(2), for example, would return every other element from the enumerable:

[1, 2, 3, 4, 5, 6].every(2)               -> [1, 3, 5]
[1, 2, 3, 4, 5, 6].every(2) { |i| ... }   -> nil


23
24
25
26
27
28
29
30
31
# File 'lib/quality_extensions/enumerable/every.rb', line 23

def every(n)
  result = [] unless block_given?
  each_with_index do |object, i|
    if i % n == 0
      block_given?? yield(object) : result << object
    end
  end
  return block_given?? nil : result
end

#gradiate(options = {}) ⇒ Object

Sorts objects in the enumeration and applies a color scale to them.

Color ranges must be in the form [x, y], where x and y are either fixnums (e.g. 255, 0xFF) or hexadecimal strings (e.g. ‘FF’).

Ranges can be provided for each RGB color e.g.

gradiate(:red => red_range)

…and a default range (for all colors) can be set using :all e.g.

gradiate(:all => default_range, :green => green_range)

If no color ranges are supplied then the sorted enumeration will be returned.

Objects contained in the enumeration are expected to have a color (or colour) attribute/method that returns a Color::RGB object (or similar).

By default, objects are sorted using :to_i. This can be overidden by setting options[:compare_using] to a different method symbol.

By default, objects are ordered “smallest” first. To reverse this set options[:order] to either :desc or :reverse.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/quality_extensions/color/gradiate.rb', line 42

def gradiate(options={})
  ranges = [:red, :green, :blue].map do |col|
    if range = (options[col] || options[:all])
      a, b = range.map { |x| x.respond_to?(:hex) ? x.hex : x.to_i }
      a, b = b, a if a > b # smallest first
      c = b.diff(a) / (self.size - 1)
      next (a..b).every(c)
    else [] end
  end

  objects = sort_by { |object| object.send(options[:compare_using] || :to_i) }
  objects = objects.reverse if [:desc, :reverse].include?(options[:order])
  objects.zip(*ranges).collect do |object, red, green, blue|
    color = object.respond_to?(:colour) ? object.colour : object.color
    color.red = red if red
    color.green = green if green
    color.blue = blue if blue
    next object
  end
end

#grep_with_regexp_support_for_symbols(pattern, &block) ⇒ Object



89
90
91
92
93
# File 'lib/quality_extensions/symbol/match.rb', line 89

def grep_with_regexp_support_for_symbols(pattern, &block)
  map { |element|
    element.is_a?(Symbol) ? element.to_s : element
  }.grep_without_regexp_support_for_symbols(pattern, &block)
end

#map_with_index(&block) ⇒ Object



17
18
19
# File 'lib/quality_extensions/enumerable/map_with_index.rb', line 17

def map_with_index(&block)
  dup.map_with_index!(&block)
end

#map_with_index!Object



11
12
13
14
15
# File 'lib/quality_extensions/enumerable/map_with_index.rb', line 11

def map_with_index!
  each_with_index do |e, i|
    self[i] = yield(e, i)
  end
end

#select_until(inclusive = false, &block) ⇒ Object

Returns an array containing all consecutive elements of enum for which block is not false, starting at the first element. So it is very much like select, only it stops searching as soon as block ceases to be true. (That means it will stop searching immediately if the first element doesn’t match.)

This might be preferable to select, for example, if:

  • you have a very large collection of elements

  • the desired elements are expected to all be consecutively occuring and are all at the beginning of the collection

  • it would be costly to continue iterating all the way to the very end

This is probably only useful for collections that have some kind of predictable ordering (such as Arrays).

AKA: select_top_elements_that_match



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/quality_extensions/enumerable/select_while.rb', line 24

def select_until(inclusive = false, &block)
  selected = []
  inclusive ? (
    each do |item|
      selected << item
      break if block.call(item)
    end
  ) : (
    each do |item|
      break if block.call(item)
      selected << item
    end
  )
  selected
end

#select_while(&block) ⇒ Object



40
41
42
43
44
45
46
47
# File 'lib/quality_extensions/enumerable/select_while.rb', line 40

def select_while(&block)
  selected = []
  each do |item|
    break if !block.call(item)
    selected << item
  end
  selected
end