module Eco module Data module FuzzyMatch module ArrayHelpers # Keeps the start order of the `values` and consecutive `values` together/consecutive. # @param values [Array] the input array with the values. # @param range [Integer, Range] determine the lenght of the generated values. # @return [Array>] combinations of `range` length of `values`. def ngrams(values, range=2..3) [].tap do |out| if range.is_a?(Integer) n = range values_count = values.length values.each_with_index do |word, i| min = i max = i + (n - 1) break if values_count <= max out << values[min..max].join(' ') end out.uniq! else range.each {|n| out.concat(ngrams(values, n))} out.uniq! end end end # Keeps the start order of the `values` of the input `Array` `values`. # It does **not** keep consecutive `values` together (it can jump/skip items). # @param values [Array] the input array with the values. # @param range [Integer, Range] determine the lenght of the generated values. # @return [Array>] combinations of `range` length of `values` def combinations(values, range=2..3) if range.is_a?(Integer) values.combination(range).to_a else range.flat_map {|size| values.combination(size).to_a} end end # It includes `combinations` that break the initial order of the `Array`. # It does **not** keep consecutive `values` together (it can jump/skip items). # @param values [Array] the input array with the values. # @param range [Integer, Range] determine the lenght of the generated values. # @return [Array>] permutations of `range` length of `values` def permutations(values, range=2..3) combinations(values, range).tap do |out| range = range.is_a?(Integer)? (range..range) : range out.dup.select do |item| range.include?(item.length) end.each do |comb| comb.permutation.to_a.tap do |perms| perms.each {|perm| out << perm} end end out.uniq! end end # Helper to praper facet structure # @param values1 [Array] the input array with the values to have their facet against. # @param values2 [Array] the input array with the values to facet against. # @return [Hash] where `keys` are `values1` and `value` of each `key` all `values2` def facet(values1, values2) {}.tap do |out| next unless values1.is_a?(Enumerable) values1 = values1.is_a?(Hash) ? values1.values : values1.to_a values1.each {|val| out[val] = values2.dup} end end end end end end