Sha256: 264867c25d249a70ab9c440924ddf9e858424ef2521998c58393632f967fe719

Contents?: true

Size: 1.37 KB

Versions: 1

Compression:

Stored size: 1.37 KB

Contents

module GraphQL::Models::HashCombiner
  class << self
    # Takes a set of hashes that represent conditions, and combines them into the smallest number of hashes
    def combine(hashes)
      # Group the hashes by keys. If they are querying different columns, they can't be combined
      by_keys = hashes.group_by { |h| h.keys }
      by_keys.map { |keys, values| combine_core(values, keys) }.flatten
    end

    private

    def combine_core(hashes, keys)
      return [] if keys.blank?

      # If there's only one key in each of the hashes, then combine that into a single hash with an array
      if keys.length == 1
        values = hashes.map { |h| h[keys[0]] }
        return [{ keys[0] => values.uniq }]
      end

      # Get the most commonly occuring value in the hash, and remove it from the keys.
      # Return one hash for each unique value.
      min_key = keys.min_by { |k| hashes.map { |h| h[k] }.uniq.count }
      inner_keys = keys.dup
      inner_keys.delete(min_key)

      # Group the hashes based on the value that they have for that key
      grouped = hashes.group_by { |h| h[min_key] }

      grouped = grouped.map do |key_value, inner_hashes|
        combined = combine_core(inner_hashes, inner_keys)
        merge_with = { min_key => key_value }

        combined.map { |reduced_hash| merge_with.merge(reduced_hash) }
      end

      grouped.flatten
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
graphql-activerecord-0.7.0 lib/graphql/models/hash_combiner.rb