Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@maetl
Last active September 30, 2015 21:54
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save maetl/4542fc2390eb8701284e to your computer and use it in GitHub Desktop.
Save maetl/4542fc2390eb8701284e to your computer and use it in GitHub Desktop.
Using transproc to compose various hash transformations and mappings
require 'transproc/all'
require 'addressable/uri'
##
# Convert string keys to symbols
#
transform = Transproc(:symbolize_keys)
data = {
'name' => 'Mark Rickerby',
'website' => 'http://maetl.net'
}
puts transform.call(data)
# => {:name=>"Mark Rickerby", :website=>"http://maetl.net"}
##
# Transform key names
#
transform = Transproc(:map_hash, :name => :full_name, :website => :external_uri)
data = {
:name => 'Mark Rickerby',
:website => 'http://maetl.net'
}
puts transform.call(data)
# => {:full_name=>"Mark Rickerby", :external_uri=>"http://maetl.net"}
##
# Mapping to a value object using default coercion
#
transform = Transproc(:map_key, :postcode, Transproc(:to_integer))
data = {
:postcode => '2008'
}
puts transform.call(data)
# => {:postcode=>2008}
##
# Compose a chain of default coercions
#
integer = Transproc(:map_key, :postcode, Transproc(:to_integer))
datetime = Transproc(:map_key, :updated_at, Transproc(:to_datetime))
boolean = Transproc(:map_key, :is_active, Transproc(:to_boolean))
transform = integer + datetime + boolean
data = {
:postcode => '2008',
:updated_at => '2015-03-28',
:is_active => 'true'
}
puts transform.call(data)
# => {:postcode=>2008, :updated_at=>#<DateTime: 2015-03-28T00:00:00+00:00 ((2457110j,0s,0n),+0s,2299161j)>, :is_active=>true}
##
# Mapping to a URI object using a custom coercion
#
module Transproc
register(:to_uri) do |value|
Addressable::URI.parse(value)
end
end
transform = Transproc(:map_key, :href, Transproc(:to_uri))
data = {
:href => 'http://maetl.net/about/me'
}
puts transform.call(data)
# => {:href=>#<Addressable::URI:0x3ff125cb47c8 URI:http://maetl.net/about/me>}
##
# Group multiple items into a nested array
#
transform = Transproc(:group, :links, [:website])
data = [
{ :name => 'Mark Rickerby', :website => 'http://maetl.net' },
{ :name => 'Mark Rickerby', :website => 'http://editorial.technology' }
]
puts transform.call(data)
# => {:name=>"Mark Rickerby", :links=>[{:website=>"http://maetl.net"}, {:website=>"http://editorial.technology"}]}
##
# Compose functional transforms
#
map = Transproc(:map_array, Transproc(:map_hash, :website => :href))
group = Transproc(:group, :links, [:href])
transform = map + group
data = [
{ :name => 'Mark Rickerby', :website => 'http://maetl.net' },
{ :name => 'Mark Rickerby', :website => 'http://editorial.technology' }
]
puts transform.call(data)
# => {:name=>"Mark Rickerby", :links=>[{:href=>"http://maetl.net"}, {:href=>"http://editorial.technology"}]}
##
# Join keys together using a default separator token (single space)
#
module Transproc
SEPARATOR = ' '.freeze
register(:join_keys) do |hash, mapping|
Transproc(:join_keys!, mapping)[Hash[hash]]
end
register(:join_keys!) do |hash, mapping|
mapping.each do |to, from|
hash[to] = hash.select { |k,v| from.include?(k) }.values.join(SEPARATOR)
from.each { |k| hash.delete(k) }
end
hash
end
end
transform = Transproc(:join_keys, :name => [:first_name, :last_name])
data = {
:first_name => 'Mark',
:last_name => 'Rickerby'
}
puts transform.call(data)
# => {:name=>"Mark Rickerby"}
##
# Split keys based on a default separator token
#
module Transproc
register(:split_keys) do |hash, mapping|
Transproc(:split_keys!, mapping)[Hash[hash]]
end
register(:split_keys!) do |hash, mapping|
mapping.each do |to, from|
hash[from].split(SEPARATOR).each_with_index do |value, index|
hash[to[index]] = value
end
hash.delete(from)
end
hash
end
end
transform = Transproc(:split_keys, [:first_name, :last_name] => :name)
data = {
:name => 'Mark Rickerby'
}
puts transform.call(data)
# => {:first_name=>"Mark", :last_name=>"Rickerby"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment