Module: Enumerable

Defined in:
lib/everythingrb/enumerable.rb

Overview

Extensions to Ruby’s core Enumerable module

Provides:

  • #join_map: Combine filter_map and join operations into one step

  • #group_by_key: Group elements by key or nested keys, simplifying collection organization

Examples:

require "everythingrb/enumerable"
(1..5).join_map(" | ") { |n| "item-#{n}" if n.even? }  # => "item-2 | item-4"
users.group_by_key(:role)  # Groups users by their role

Instance Method Summary collapse

Instance Method Details

#group_by_key(*keys) {|value| ... } ⇒ Hash, Enumerator

Groups elements by a given key or nested keys

Examples:

Group by a single key

users = [
  {name: "Alice", role: "admin"},
  {name: "Bob", role: "user"},
  {name: "Charlie", role: "admin"}
]
users.group_by_key(:role)
# => {"admin"=>[{name: "Alice", role: "admin"}, {name: "Charlie", role: "admin"}],
#     "user"=>[{name: "Bob", role: "user"}]}

Group by nested keys

data = [
  {department: {name: "Sales"}, employee: "Alice"},
  {department: {name: "IT"}, employee: "Bob"},
  {department: {name: "Sales"}, employee: "Charlie"}
]
data.group_by_key(:department, :name)
# => {"Sales"=>[{department: {name: "Sales"}, employee: "Alice"},
#                {department: {name: "Sales"}, employee: "Charlie"}],
#     "IT"=>[{department: {name: "IT"}, employee: "Bob"}]}

With transformation block

users.group_by_key(:role) { |role| role.upcase }
# => {"ADMIN"=>[{name: "Alice", role: "admin"}, {name: "Charlie", role: "admin"}],
#     "USER"=>[{name: "Bob", role: "user"}]}

Yields:

  • (value)

    Optional block to transform the key value before grouping

Yield Parameters:

  • value (Object)

    The value at the specified key(s)

Yield Returns:

  • (Object)

    The transformed value to use as the group key



89
90
91
92
93
94
95
# File 'lib/everythingrb/enumerable.rb', line 89

def group_by_key(*keys, &block)
  group_by do |value|
    result = value.respond_to?(:dig) ? value.dig(*keys) : nil
    result = yield(result) if block
    result
  end
end

#join_map(join_with = "", with_index: false) {|element, index| ... } ⇒ String, Enumerator

Combines filter_map and join operations

Examples:

Without index

[1, 2, nil, 3].join_map(" ") { |n| n&.to_s if n&.odd? }
# => "1 3"

With index

["a", "b", "c"].join_map(", ", with_index: true) { |char, i| "#{i}:#{char}" }
# => "0:a, 1:b, 2:c"

Using with other enumerables

(1..10).join_map(" | ") { |n| "num#{n}" if n.even? }
# => "num2 | num4 | num6 | num8 | num10"

Yields:

  • (element, index)

    Block that filters and transforms elements

Yield Parameters:

  • element (Object)

    The current element

  • index (Integer)

    The index of the current element (only if with_index: true)



41
42
43
44
45
46
47
48
49
# File 'lib/everythingrb/enumerable.rb', line 41

def join_map(join_with = "", with_index: false, &block)
  block = ->(i) { i } if block.nil?

  if with_index
    filter_map.with_index(&block).join(join_with)
  else
    filter_map(&block).join(join_with)
  end
end