Module: Forester::Aggregators

Included in:
TreeNode
Defined in:
lib/forester/tree_node_ext/aggregators.rb

Instance Method Summary collapse

Instance Method Details

#group_by_sibling_subtrees(options = {}) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/forester/tree_node_ext/aggregators.rb', line 58

def group_by_sibling_subtrees(options = {})
  default_options = {
    level:             1,
    group_field:       'name',
    aggregation_field: 'value',
    if_field_missing:  -> (node) { [] },
    ancestry_in_keys:  false, # if false, with_root is ignored
    with_root:         false
  }
  options = default_options.merge(options)

  nodes_of_level(options[:level]).each_with_object({}) do |node, hash|
    key =
      if options[:ancestry_in_keys]
        nodes_for_key = node.with_ancestry({ include_root: options[:with_root] })
        nodes_for_key.map { |n| get_or_id(n, options[:group_field]) }
      else
        get_or_id(node, options[:group_field])
      end

    value = node.own_and_descendants(options[:aggregation_field], &options[:if_field_missing])

    hash[key] = value
  end
end

#nodes_with(field, values, options = {}) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/forester/tree_node_ext/aggregators.rb', line 10

def nodes_with(field, values, options = {})
  default_options = {
    single: false
  }
  options = default_options.merge(options)

  method = options[:single] ? :find : :select
  found_nodes = each_node.public_send(method) do |node|
    not ( Array(node.get(field) { :no_match }) & Array(values) ).empty?
  end

  Array(found_nodes)
end

#own_and_descendants(field, &if_missing) ⇒ Object



4
5
6
7
8
# File 'lib/forester/tree_node_ext/aggregators.rb', line 4

def own_and_descendants(field, &if_missing)
  if_missing = -> (node) { [] } unless block_given?

  flat_map { |node| Array(node.get(field, &if_missing)) }
end

#search(options) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/forester/tree_node_ext/aggregators.rb', line 39

def search(options)
  default_options = {
    single_node: false,
    by_field:    :name,
    keywords:    :missing_search_keywords,
    then_get:    :nodes, # if :nodes, subtree is ignored
    subtree:     true
  }
  options = default_options.merge(options)

  found_nodes = nodes_with(options[:by_field], options[:keywords], { single: options[:single_node] } )

  return found_nodes if options[:then_get] == :nodes

  found_nodes.flat_map do |node|
    node.get(options[:then_get], { subtree: options[:subtree] })
  end
end

#with_ancestry(options = {}) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/forester/tree_node_ext/aggregators.rb', line 24

def with_ancestry(options = {})
  default_options = {
    include_root: true,
    include_self: true,
    descending:   true
  }
  options = default_options.merge(options)

  ancestors = self.parentage           || []
  ancestors = ancestors[0...-1]        unless options[:include_root]
  ancestors = ancestors.unshift(self)  if     options[:include_self]

  options[:descending] ? ancestors.reverse : ancestors
end