Module: Transproc::ArrayTransformations

Extended by:
Functions
Defined in:
lib/transproc/array.rb

Overview

Transformation functions for Array objects

Examples:

require 'transproc/array'

include Transproc::Helper

fn = t(:map_array, t(:symbolize_keys)) >> t(:wrap, :address, [:city, :zipcode])

fn.call(
  [
    { 'city' => 'Boston', 'zipcode' => '123' },
    { 'city' => 'NYC', 'zipcode' => '312' }
  ]
)
# => [{:address=>{:city=>"Boston", :zipcode=>"123"}}, {:address=>{:city=>"NYC", :zipcode=>"312"}}]

Instance Method Summary collapse

Methods included from Functions

method_added

Instance Method Details

#combine(array, mappings) ⇒ Array<Hash>

Combines two arrays by merging child items from right array using join keys

Examples:

fn = t(:combine, [[:tasks, name: :user]])

fn.call([[{ name: 'Jane' }], [{ user: 'Jane', title: 'One' }]])
# => [{:name=>"Jane", :tasks=>[{:user=>"Jane", :title=>"One"}]}]

Parameters:

  • array (Array<Array>)

    The input array

  • mappings (Array<Hash>)

    The mapping definitions array

Returns:

  • (Array<Hash>)


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/transproc/array.rb', line 116

def combine(array, mappings)
  root, groups = array

  cache = Hash.new { |h, k| h[k] = Hash.new }

  root.map { |parent|
    child_hash = {}

    groups.each_with_index do |candidates, index|
      key, keys, group_mappings = mappings[index]

      children =
        if group_mappings
          combine(candidates, group_mappings)
        else
          candidates
        end

      child_keys = keys.values
      pkey_value = parent.values_at(*keys.keys) # ugh

      cache[key][child_keys] ||= children.group_by { |child|
        child.values_at(*child_keys)
      }
      child_arr = cache[key][child_keys][pkey_value] || []

      child_hash.update(key => child_arr)
    end

    parent.merge(child_hash)
  }
end

#extract_key(array, key) ⇒ Array

Converts the array of hashes to array of values, extracted by given key

Examples:

fn = t(:extract_key, :name)
fn.call [
  { name: 'Alice', role: 'sender' },
  { name: 'Bob', role: 'receiver' },
  { role: 'listener' }
]
# => ['Alice', 'Bob', nil]

Parameters:

  • array (Array<Hash>)

    The input array of hashes

  • key (Object)

    The key to extract values by

Returns:

  • (Array)


166
167
168
# File 'lib/transproc/array.rb', line 166

def extract_key(array, key)
  extract_key!(Array[*array], key)
end

#extract_key!(array, key) ⇒ Object

Same as ‘extract_key` but mutates the array

See Also:



175
176
177
# File 'lib/transproc/array.rb', line 175

def extract_key!(array, key)
  map_array!(array, -> v { v[key] })
end

#group(array, key, keys) ⇒ Array

Group array values using provided root key and value keys

Examples:

fn = Transproc(:group, :tags, [:tag_name])

fn.call [
  { task: 'Group it', tag: 'task' },
  { task: 'Group it', tag: 'important' }
]
# => [{ task: 'Group it', tags: [{ tag: 'task' }, { tag: 'important' }]]

Parameters:

  • array (Array)

    The input array

  • key (Object)

    The nesting root key

  • keys (Object)

    The nesting value keys

Returns:

  • (Array)


89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/transproc/array.rb', line 89

def group(array, key, keys)
  grouped = Hash.new { |h, k| h[k] = [] }
  array.each do |hash|
    hash = hash.dup
    child = {}
    keys.each { |k| child[k] = hash.delete(k) }
    grouped[hash] << child
  end
  grouped.map do |root, children|
    root.merge(key => children)
  end
end

#map_array(array, fn) ⇒ Array

Map array values using transformation function

Examples:


fn = Transproc(:map_array, -> v { v.upcase })

fn.call ['foo', 'bar'] # => ["FOO", "BAR"]

Parameters:

  • array (Array)

    The input array

  • fn (Proc)

    The transformation function

Returns:

  • (Array)


39
40
41
# File 'lib/transproc/array.rb', line 39

def map_array(array, fn)
  map_array!(Array[*array], fn)
end

#map_array!(array, fn) ⇒ Object

Same as ‘map_array` but mutates the array

See Also:



48
49
50
# File 'lib/transproc/array.rb', line 48

def map_array!(array, fn)
  array.map! { |value| fn[value] }
end

#wrap(array, key, keys) ⇒ Array

Wrap array values using HashTransformations.nest function

Examples:

fn = Transproc(:wrap, :address, [:city, :zipcode])

fn.call [{ city: 'NYC', zipcode: '123' }]
# => [{ address: { city: 'NYC', zipcode: '123' } }]

Parameters:

  • array (Array)

    The input array

  • key (Object)

    The nesting root key

  • keys (Object)

    The nesting value keys

Returns:

  • (Array)


67
68
69
# File 'lib/transproc/array.rb', line 67

def wrap(array, key, keys)
  map_array(array, Transproc(:nest, key, keys))
end