Module: HashHelper::Percentage

Includes:
DeepSum
Included in:
Hash
Defined in:
lib/hash_helper/percentage.rb

Instance Method Summary collapse

Methods included from DeepSum

#deep_sum

Instance Method Details

#deep_transform_values_to_percentages(relative: true, precision: nil) ⇒ Hash

Transforms all numeric values in the hash into percentages.

Examples:

Global percentages (relative: false)

{ a: 50, b: { c: 30, d: 20 }, e: 100 }.deep_transform_values_to_percentages
# => { a: 25.0, b: { c: 15.0, d: 10.0 }, e: 50.0 }

Relative percentages for each layer (relative: true)

{ a: 50, b: { c: 30, d: 20 }, e: 100 }.deep_transform_values_to_percentages(relative: true)
# => { a: 50.0, b: { c: 60.0, d: 40.0 }, e: 100.0 }

Parameters:

  • relative (Boolean) (defaults to: true)

    If ‘true`, calculates percentages relative to the current layer. If `false`, calculates percentages relative to the entire hash. Defaults to `true`.

  • precision (Integer, nil) (defaults to: nil)

    The number of decimal places to round the percentages to. Defaults to no rounding.

Returns:

  • (Hash)

    A new hash with numeric values transformed into percentages.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/hash_helper/percentage.rb', line 22

def deep_transform_values_to_percentages(relative: true, precision: nil)
  total_sum = deep_sum

  calculate_percentage = lambda do |value|
    return value unless value.is_a?(Numeric)
    return value unless total_sum.positive?

    percentage = (value / total_sum.to_f * 100)
    precision ? percentage.round(precision) : percentage
  end

  unless relative
    return deep_transform_values { |value| calculate_percentage.call(value) }
  end

  transform_values do |value|
    case value
    when Hash
      value.deep_transform_values_to_percentages(relative: relative, precision: precision)
    else
      calculate_percentage.call(value)
    end
  end
end