Class: Hash

Inherits:
Object
  • Object
show all
Defined in:
lib/hash_sample.rb

Overview

monkey-patched Hash module

Instance Method Summary collapse

Instance Method Details

#_check_weighted_params(*_args) ⇒ Object

internal method to validate parameters

Raises:

  • (ArgumentError)


52
53
54
55
56
57
58
59
60
61
# File 'lib/hash_sample.rb', line 52

def _check_weighted_params(*_args)
  sum_weights = 0
  each_value do |v|
    raise ArgumentError, "All weights should be numeric unlike #{v}" unless v.is_a? Numeric

    sum_weights += v if v.positive?
  end

  raise ArgumentError, "At least one weight should be > 0" unless sum_weights.positive? || empty?
end

#sample(n = 1) ⇒ Hash

Choose a random key=>value pair or n random pairs from the hash.

The elements are chosen by using random and unique indices in order to ensure that each element doesn’t includes more than once. If the hash is empty it returns an empty hash. If the hash contains less than n unique keys, the copy of whole hash will be returned, none of keys will be lost.



11
12
13
# File 'lib/hash_sample.rb', line 11

def sample(n = 1)
  to_a.sample(n).to_h
end

#wchoiceObject #wchoice(n) ⇒ Array

Choose 1 or n random keys from the hash, according to weights defined in hash values (weighted random sampling with replacement)

The keys are chosen by using random according to its weights and can be repeated in result. If the hash is empty the first form returns nil and the second form returns an empty array. All weights should be Numeric. Zero or negative weighs will be ignored.

Example
p {'_' => 9, 'a' => 1}.wchoice(10)  # ["_", "a", "_", "_", "_", "_", "_", "_", "_", "_"]


40
41
42
43
44
45
46
47
48
49
# File 'lib/hash_sample.rb', line 40

def wchoice(*args)
  _check_weighted_params
  n = args.first || 1
  res = []
  n.times do
    tmp = max_by { |_, weight| weight.positive? ? rand**(1.0 / weight) : 0 }
    res << tmp.first unless tmp.nil?
  end
  return args.empty? ? res.first : res
end

#wchoices(*args) ⇒ Object

alias for wchoice



17
18
19
# File 'lib/hash_sample.rb', line 17

def wchoices(*args)
  wchoice(*args)
end

#wsampleObject #wsample(n) ⇒ Array

Choose 1 or n distinct random keys from the hash, according to weights defined in hash values (weighted random sampling without replacement)

When there are no sufficient distinct samples to return, the result will contain less than n samples If the hash is empty the first form returns nil and the second form returns an empty array. All weights should be Numeric. Zero or negative weighs will be ignored.

Example
p {'_' => 9, 'a' => 1}.wsample(10)  # ["_", "a"]


82
83
84
85
86
87
# File 'lib/hash_sample.rb', line 82

def wsample(*args)
  _check_weighted_params
  n = args.first || 1
  res = max_by(n) { |_, weight| weight.positive? ? rand**(1.0 / weight) : 0 }.map(&:first)
  return args.empty? ? res.first : res
end

#wsamples(*args) ⇒ Object

alias for wsample



91
92
93
# File 'lib/hash_sample.rb', line 91

def wsamples(*args)
  wsample(*args)
end