Module: ConditionalSample::MixMe

Defined in:
lib/conditional_sample/public.rb,
lib/conditional_sample/private.rb

Overview

This module is suitable as a mixin, using the results of self#to_a

It is automatically included in Array, so each of these methods are added to Array when you require ‘conditional_sample’

For both methods, the ‘conditions’ array must contain boolean procs using args |arr, elem|

arr

a reference to the current array that has been built up through the recursion chain.

elem

a reference to the current element being considered.

Instance Method Summary collapse

Instance Method Details

#conditional_permutation(conditions, seconds = nil) ⇒ Object

Return a permutation of ‘array’ where each element validates to the same index in a ‘conditions’ array of procs that return Boolean.

The output is an array that is a complete permutation of the input array. i.e. output.length == array.length

Any elements in the array that are extra to the number of conditions will be assumed valid.

array = [1,2,3,4,5].shuffle
conditions = [
  proc { |arr, elem| elem < 2},
  proc { |arr, elem| elem > 2},
  proc { |arr, elem| elem > 1}
]
array.conditional_permutation(conditions)

possible output => [1, 3, 4, 5, 2]


40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/conditional_sample/public.rb', line 40

def conditional_permutation conditions, seconds = nil
  ConditionalSample::method_assert(self, 'to_a')

  # Convert the conditions to an array.

  conditions =
    ConditionalSample::to_conditions_array(conditions, proc { true })

  # Run the recursion, and rescue after a number of seconds.

  timeout_rescue(seconds, []) do
    conditional_permutation_recurse(self.to_a, conditions).tap{ |i| i.pop }
  end
end

#conditional_sample(conditions, seconds = nil) ⇒ Object

Return values from ‘array’ where each element validates to the same index in a ‘conditions’ array of procs that return Boolean.

The output is an array of conditions.length that is a partial permutation of the input array, where satisfies only the conditions.

Any elements in the array that are extra to the number of conditions will not be output.

array = [1,2,3,4,5].shuffle
conditions = [
  proc { |arr, elem| elem < 2},
  proc { |arr, elem| elem > 2},
  proc { |arr, elem| elem > 1}
]
array.conditional_sample(conditions)

possible output => [1, 5, 3]


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/conditional_sample/public.rb', line 73

def conditional_sample conditions, seconds = nil
  ConditionalSample::method_assert(self, 'to_a')

  # Would always return [] anyway if there are more conditions than

  # inputs, this just avoids running the complex recursion code.

  return [] if conditions.length > self.to_a.length

  # Convert the conditions to an array.

  conditions =
    ConditionalSample::to_conditions_array(conditions, proc { true })

  # Run the recursion, and rescue after a number of seconds.

  timeout_rescue(seconds, []) do
    conditional_sample_recurse(self.to_a, conditions).tap{ |i| i.pop }
  end
end