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

#add_keys(array, keys) ⇒ Array

Adds missing keys with nil value to all tuples in array

Parameters:

  • keys (Array)

Returns:

  • (Array)


241
242
243
# File 'lib/transproc/array.rb', line 241

def add_keys(array, keys)
  add_keys!(Array[*array], keys)
end

#add_keys!(array, keys) ⇒ Object

Same as ‘add_keys` but mutates the array

See Also:



250
251
252
253
# File 'lib/transproc/array.rb', line 250

def add_keys!(array, keys)
  base = keys.inject({}) { |a, e| a.merge(e => nil) }
  map_array!(array, -> v { base.merge(v) })
end

#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>)


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/transproc/array.rb', line 142

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

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

  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)


192
193
194
# File 'lib/transproc/array.rb', line 192

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:



201
202
203
# File 'lib/transproc/array.rb', line 201

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
101
102
# 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[hash]

    old_group = Transproc::Coercions.to_tuples(hash.delete(key))
    new_group = keys.inject({}) { |a, e| a.merge(e => hash.delete(e)) }

    grouped[hash] << old_group.map { |item| item.merge(new_group) }
  end
  grouped.map do |root, children|
    root.merge(key => children.flatten)
  end
end

#insert_key(array, key) ⇒ Array

Wraps every value of the array to tuple with given key

The transformation partially inverses the ‘extract_key`.

Examples:

fn = t(:insert_key, 'name')
fn.call ['Alice', 'Bob', nil]
# => [{ 'name' => 'Alice' }, { 'name' => 'Bob' }, { 'name' => nil }]

Parameters:

  • array (Array<Hash>)

    The input array of hashes

  • key (Object)

    The key to extract values by

Returns:

  • (Array)


220
221
222
# File 'lib/transproc/array.rb', line 220

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

#insert_key!(array, key) ⇒ Object

Same as ‘insert_key` but mutates the array

See Also:



229
230
231
# File 'lib/transproc/array.rb', line 229

def insert_key!(array, key)
  map_array!(array, -> v { { key => v } })
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

#ungroup(array, key, keys) ⇒ Array

Ungroup array values using provided root key and value keys

Examples:

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

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

Parameters:

  • array (Array)

    The input array

  • key (Object)

    The nesting root key

  • keys (Object)

    The nesting value keys

Returns:

  • (Array)


124
125
126
# File 'lib/transproc/array.rb', line 124

def ungroup(array, key, keys)
  array.flat_map { |item| HashTransformations.split(item, key, keys) }
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