-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeepop.rb
More file actions
112 lines (98 loc) · 2.98 KB
/
Copy pathdeepop.rb
File metadata and controls
112 lines (98 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
56
57
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
module Enumerable
#Extentions for mixed data structures consisting of nested Arrays and Hashes
#---------------------------------------------------------------------------
# Generalized recursive sender of iterator methods to Enumerable trees.
def deep_send(iterator)
deep =->(x) do
case x
when Enumerable
x.send(iterator){|e| deep.(e)}
else
yield x
end
end
deep.(self)
end
# Like #each, but it loops through every Array and Hash in a nested Array/Hash data structure.
# For Hashes it iterates through the keys and for Arrays it iterates through the values.
def each_deep
self.deep_send("each_values"){|e| yield e}
end
# Like #map, but it maps every element in a nested Hash/Array data structure.
# For an Array is maps the elements and for a Hash it maps the values
def map_deep
self.deep_send("map_values"){|e| yield e}
end
# A #map that works both for Arrays and Hashes. For Hashes it keeps the original keys.
def map_values
case self
when Array
self.map{|e| yield e}
when Hash
self.map{|k,v| [k,(yield v)]}.to_h
end
end
# An #each that works both for Arrays and Hashes. For Hashes it iterates over the values.
def each_values
case self
when Array
array = self
when Hash
array = self.values
end
array.each{|e| yield e}
end
# Like #flatten, but it also flattens Hashes inside a nested Hash/Array data structure.
# The values of Hashes are pushed into the output array and the keys are discarded
def trample
out = []
self.each_deep{|e| out << e}
out
end
# Like #include, but it searches through all Array elements and Hash values.
def include_deep?(input)
self.each_deep{|e| return true if e == input}
return false
end
# Selects a hash of all Hash sub-branches based on the key
# Returns an array of the values of found branches
def select_branches_by_key
branches = []
deep =->(x){
case x
when Array
x.each{|e| deep.(e)}
when Hash
x.each{|k,v| deep.(v) }
selected = x.select{|k,v| yield k}
branches |= selected.values if selected != {}
end
}
deep.(self)
branches
end
end
# # DEMO
# # ----
#
# data_structure = [1,2,[31,32],4,[{a:51,b:52,c:[531,532,[5331,5332]]},{a:54,b:55}],6]
# puts "original data structure:"
# puts data_structure.inspect
# puts
# puts "puts #each iteratee of data structure:"
# data_structure.each_deep{|x| puts x}
# puts
# puts "mapped data structure after applying *10"
# puts data_structure.map_deep{|x| x.to_s.to_i*10}.inspect
# puts
# puts "flattened data structure:"
# puts data_structure.flatten.inspect
# puts
# puts "trampled data structure"
# puts data_structure.trample.inspect
# puts
# puts "find? 5332 somwhere in data structure"
# puts data_structure.include_deep?(5332)
# puts
# puts "select all braches labeled ':a' in data structure"
# puts data_structure.select_branches_by_key{|k| k== :a}.inspect