Sha256: aa0af924543f98e6b5d25189583a0c5ad176a745f59253287081f7a29d4ef34c

Contents?: true

Size: 1.68 KB

Versions: 1

Compression:

Stored size: 1.68 KB

Contents

module Transproc
  module ArrayTransformations
    class Combine
      class << self
        def combine(array, mappings)
          root, nodes = array
          return root if nodes.nil?
          groups = group_nodes(nodes, mappings)

          root.map do |element|
            element.dup.tap { |copy| add_groups_to_element(copy, groups, mappings) }
          end
        end

        private

        def add_groups_to_element(element, groups, mappings)
          groups.each_with_index do |candidates, index|
            mapping = mappings[index]
            resource_key = mapping[0]
            element[resource_key] = element_candidates(element, candidates, mapping[1].keys)
          end
        end

        def element_candidates(element, candidates, keys)
          candidates[element_candidates_key(element, keys)] || []
        end

        def group_nodes(nodes, mappings)
          nodes.each_with_index.map do |candidates, index|
            mapping = mappings[index]
            group_candidates(candidates, mapping)
          end
        end

        def group_candidates(candidates, mapping)
          nested_mapping = mapping[2]
          candidates = combine(candidates, nested_mapping) unless nested_mapping.nil?
          group_candidates_by_keys(candidates, mapping[1].values)
        end

        def group_candidates_by_keys(candidates, keys)
          return candidates.group_by { |a| a.values_at(*keys) } if keys.size > 1

          key = keys.first
          candidates.group_by { |a| a[key] }
        end

        def element_candidates_key(element, keys)
          return element.values_at(*keys) if keys.size > 1
          element[keys.first]
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
transproc-1.0.1 lib/transproc/array/combine.rb