Class: Eco::API::Organization::TagTree
- Inherits:
-
Object
- Object
- Eco::API::Organization::TagTree
- Defined in:
- lib/eco/api/organization/tag_tree.rb
Overview
Provides helpers to deal with tagtrees.
Instance Attribute Summary collapse
-
#children_count ⇒ Object
readonly
Returns the value of attribute children_count.
-
#depth ⇒ Object
readonly
Returns the value of attribute depth.
-
#enviro ⇒ Object
readonly
Returns the value of attribute enviro.
-
#id ⇒ Object
(also: #tag)
Returns the value of attribute id.
-
#name ⇒ Object
Returns the value of attribute name.
-
#nodes ⇒ Object
readonly
Returns the value of attribute nodes.
-
#path(key = nil) ⇒ Array<String>
readonly
Finds the path from a node
keyto its root node in the tree.
Instance Method Summary collapse
-
#as_json ⇒ Array[Hash]
Where
Hashis anode{"tag" => TAG, "nodes": Array[Hash]}. -
#count ⇒ Integer
The number of locations.
-
#default_tag(*values) ⇒ String
Helper to decide which among the tags will be the default.
-
#diff(tagtree, differences: {}, level: 0, **options) ⇒ Array
With the differences.
- #dup ⇒ Eco::API::Organization::TagTree
-
#empty? ⇒ Boolean
trueif there are tags in the node,falseotherwise. -
#filter_tags(list) ⇒ Array<String>
Filters tags out that do not belong to the tree.
-
#flat? ⇒ Integer
If there's only top level.
-
#initialize(tagtree = [], name: nil, id: nil, depth: -1,, path: [], enviro: nil) ⇒ TagTree
constructor
A new instance of TagTree.
-
#leafs ⇒ Array<String>
Returns all the tags with no children.
-
#node(key) ⇒ TagTree?
Finds a subtree node.
-
#subtag?(key) ⇒ Boolean
Verifies if a tag exists in the subtree(s).
-
#subtags ⇒ Array<String>
Gets all but the upper level tags of the current node tree.
-
#tag?(key) ⇒ Boolean
Verifies if a tag exists in the tree.
-
#tags(depth: nil) ⇒ Array<String>
Gets all the tags of the current node tree.
- #top? ⇒ Boolean
-
#total_depth ⇒ Integer
The highest
depthof all the children. -
#user_tags(initial: [], final: [], preserve_custom: true, add_custom: false) ⇒ Array<String>
Helper to assign tags to a person account.
Constructor Details
#initialize(tagtree = [], name: nil, id: nil, depth: -1,, path: [], enviro: nil) ⇒ TagTree
Returns a new instance of TagTree.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/eco/api/organization/tag_tree.rb', line 24 def initialize(tagtree = [], name: nil, id: nil, depth: -1, path: [], enviro: nil) case tagtree when String @source = JSON.parse(tagtree) else @source = tagtree end fatal("You are trying to initialize a TagTree with a null tagtree") if !@source fatal("Expecting Environment object. Given: #{enviro}") if enviro && !enviro.is_a?(API::Common::Session::Environment) @enviro = enviro @depth = depth if @source.is_a?(Array) @id = id @name = name @nodes = @source else @id = @source.values_at('tag', 'id').compact.first&.upcase @name = @source['name'] @nodes = @source['nodes'] || [] end @path = path || [] @path.push(@id) unless top? @nodes = nodes.map do |cnode| TagTree.new(cnode, depth: @depth + 1, path: @path.dup, enviro: @enviro) end @children_count = @nodes.count init_hashes end |
Instance Attribute Details
#children_count ⇒ Object (readonly)
Returns the value of attribute children_count.
10 11 12 |
# File 'lib/eco/api/organization/tag_tree.rb', line 10 def children_count @children_count end |
#depth ⇒ Object (readonly)
Returns the value of attribute depth.
11 12 13 |
# File 'lib/eco/api/organization/tag_tree.rb', line 11 def depth @depth end |
#enviro ⇒ Object (readonly)
Returns the value of attribute enviro.
12 13 14 |
# File 'lib/eco/api/organization/tag_tree.rb', line 12 def enviro @enviro end |
#id ⇒ Object Also known as: tag
Returns the value of attribute id.
6 7 8 |
# File 'lib/eco/api/organization/tag_tree.rb', line 6 def id @id end |
#name ⇒ Object
Returns the value of attribute name.
8 9 10 |
# File 'lib/eco/api/organization/tag_tree.rb', line 8 def name @name end |
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
10 11 12 |
# File 'lib/eco/api/organization/tag_tree.rb', line 10 def nodes @nodes end |
#path(key = nil) ⇒ Array<String> (readonly)
the path is not relative to the subtree, but absolute to the entire tree.
Finds the path from a node key to its root node in the tree.
If key is not specified, returns the path from current node to root.
175 176 177 |
# File 'lib/eco/api/organization/tag_tree.rb', line 175 def path @path end |
Instance Method Details
#as_json ⇒ Array[Hash]
Returns where Hash is a node {"tag" => TAG, "nodes": Array[Hash]}.
73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/eco/api/organization/tag_tree.rb', line 73 def as_json nodes_json = nodes.map {|node| node.as_json} if top? nodes_json else { "id" => tag, "nodes" => nodes_json } end end |
#count ⇒ Integer
Returns the number of locations.
91 92 93 |
# File 'lib/eco/api/organization/tag_tree.rb', line 91 def count @hash_tags.keys.count end |
#default_tag(*values) ⇒ String
Helper to decide which among the tags will be the default.
- take the deepest tag (the one that is further down in the tree)
- if there are different options (several nodes at the same depth):
- take the common node between them (i.e. you have Hamilton and Auckland -> take New Zealand)
- if there's no common node between them, take the
first, unless they are at top level of the tree - to the above, take the
firstalso on top level, but only if there's 1 level for the entire tree
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/eco/api/organization/tag_tree.rb', line 223 def default_tag(*values) values = (values) nodes = []; depth = -1 values.each do |tag| raise("Couldn't find the node of #{tag} in the tag-tree definition") unless cnode = node(tag) if cnode.depth > depth nodes = [cnode] depth = cnode.depth elsif cnode.depth == depth nodes.push(cnode) end end default_tag = nil if nodes.length > 1 common = nodes.reduce(self..reverse) {|com, cnode| com & cnode.path.reverse} default_tag = common.first if common.length > 0 && depth > 0 end default_tag = nodes.first&.tag if !default_tag && ( (depth > 0) || flat?) default_tag end |
#diff(tagtree, differences: {}, level: 0, **options) ⇒ Array
Returns with the differences.
63 64 65 66 |
# File 'lib/eco/api/organization/tag_tree.rb', line 63 def diff(tagtree, differences: {}, level: 0, **) require 'hashdiff' Hashdiff.diff(self.as_json, tagtree.as_json, **.slice(:array_path, :similarity, :use_lcs)) end |
#dup ⇒ Eco::API::Organization::TagTree
58 59 60 |
# File 'lib/eco/api/organization/tag_tree.rb', line 58 def dup self.class.new(as_json) end |
#empty? ⇒ Boolean
Returns true if there are tags in the node, false otherwise.
86 87 88 |
# File 'lib/eco/api/organization/tag_tree.rb', line 86 def empty? @has_tags.empty? end |
#filter_tags(list) ⇒ Array<String>
Filters tags out that do not belong to the tree
165 166 167 168 |
# File 'lib/eco/api/organization/tag_tree.rb', line 165 def (list) return [] unless list && list.is_a?(Array) list.select {|str| tag?(str)} end |
#flat? ⇒ Integer
Returns if there's only top level.
106 107 108 |
# File 'lib/eco/api/organization/tag_tree.rb', line 106 def flat? self.total_depth <= 0 end |
#leafs ⇒ Array<String>
Returns all the tags with no children
141 142 143 144 145 |
# File 'lib/eco/api/organization/tag_tree.rb', line 141 def leafs .select do |tag| node(tag).children_count == 0 end end |
#node(key) ⇒ TagTree?
Finds a subtree node.
157 158 159 160 |
# File 'lib/eco/api/organization/tag_tree.rb', line 157 def node(key) return nil unless tag?(key) @hash_tags[key.upcase] end |
#subtag?(key) ⇒ Boolean
Verifies if a tag exists in the subtree(s).
135 136 137 |
# File 'lib/eco/api/organization/tag_tree.rb', line 135 def subtag?(key) .include?(key&.upcase) end |
#subtags ⇒ Array<String>
Gets all but the upper level tags of the current node tree.
128 129 130 |
# File 'lib/eco/api/organization/tag_tree.rb', line 128 def - (depth: depth) end |
#tag?(key) ⇒ Boolean
Verifies if a tag exists in the tree.
150 151 152 |
# File 'lib/eco/api/organization/tag_tree.rb', line 150 def tag?(key) @hash_tags.key?(key&.upcase) end |
#tags(depth: nil) ⇒ Array<String>
- this will include the upper level tag(s) as well
- to get all but the upper level tag(s) use
subtagsmethod instead
Gets all the tags of the current node tree.
116 117 118 119 120 121 122 123 124 |
# File 'lib/eco/api/organization/tag_tree.rb', line 116 def (depth: nil) if !depth || depth < 0 @hash_tags.keys else @hash_tags.select do |t, n| n.depth == depth end.keys end end |
#top? ⇒ Boolean
68 69 70 |
# File 'lib/eco/api/organization/tag_tree.rb', line 68 def top? depth == -1 end |
#total_depth ⇒ Integer
Returns the highest depth of all the children.
96 97 98 99 100 101 102 103 |
# File 'lib/eco/api/organization/tag_tree.rb', line 96 def total_depth @total_depth ||= if children_count > 0 deepest_node = nodes.max_by {|node| node.total_depth} deepest_node.depth else depth end end |
#user_tags(initial: [], final: [], preserve_custom: true, add_custom: false) ⇒ Array<String>
Helper to assign tags to a person account.
- It preserves the
:initialorder, in case the:finaltags are the same
203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/eco/api/organization/tag_tree.rb', line 203 def (initial: [], final: [], preserve_custom: true, add_custom: false) initial = [initial].flatten.compact final = [final].flatten.compact raise "Expected Array for initial: and final:" unless initial.is_a?(Array) && final.is_a?(Array) final = (final) unless add_custom custom = initial - (initial) final = final + custom if preserve_custom = final - initial # keep same order as they where (initial & final) + end |