Dry-transformer - adding a key with a value derived from a transformed array?

require 'dry/transformer/all'
require 'awesome_print'

# given this input

data = [
  { "user_id"=>279,
    "invitation_ids"=>[21, 22],
    "participants"=>["279|John|Smith", "282|Jane|Doe"]
  },
  { "user_id"=>311,
    "invitation_ids"=>[47, 95],
    "participants"=>["119|Marge|Simpson", "311|Lisa|Simpson"]
  }
]

# I'm hoping to arrive at this output

# desired output:
# [
#   {
#     :user_id => 279,
#     :latest_invitation_id => 22, # the last item from the invitation_ids array
#     :particpants => [
#                       {:id=>"279", :first_name=>"John", :last_name=>"Smith"},
#                       {:id=>"282", :first_name=>"Jane", :last_name=>"Doe"}
#                     ],
#     # the "other" participant - whose id does not match :user_id
#     :other_participant => {:id=>"282", :first_name=>"Jane", :last_name=>"Doe"} 
#   },
# ]

# this transformation gets me very close, with the exception of
#     :other_participant => {:id=>"282", :first_name=>"Jane", :last_name=>"Doe"} 
# the person whose id does not match user_id

class Functions
  extend Dry::Transformer::Registry
  import Dry::Transformer::HashTransformations
end

class Mapper < Dry::Transformer[Functions]
  import Dry::Transformer::ArrayTransformations
  import Dry::Transformer::HashTransformations

  define! do
    map_array do
      symbolize_keys
      map_value :invitation_ids, -> v { v.last }
      map_value :participants do
        map_array -> v { { id: v.split('|')[0], first_name: v.split('|')[1], last_name: v.split('|')[2] } }
      end
    end
  end
end

mapper = Mapper.new
ap mapper.(data)

# output: 

[
    [0] {
               :user_id => 279,
        :invitation_ids => 22,
          :participants => [
            [0] {
                        :id => "279",
                :first_name => "John",
                 :last_name => "Smith"
            },
            [1] {
                        :id => "282",
                :first_name => "Jane",
                 :last_name => "Doe"
            }
        ]
    },
    [1] {
               :user_id => 311,
        :invitation_ids => 95,
          :participants => [
            [0] {
                        :id => "119",
                :first_name => "Marge",
                 :last_name => "Simpson"
            },
            [1] {
                        :id => "311",
                :first_name => "Lisa",
                 :last_name => "Simpson"
            }
        ]
    }
]

How should I approach adding the :other_participant key with the desired value?

Thank you.

1 Like