nice_hash 1.15.2 → 1.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/lib/nice/hash/change_one_by_one.rb +49 -0
- data/lib/nice/hash/compare_structure.rb +69 -0
- data/lib/nice/hash/delete_nested.rb +37 -0
- data/lib/nice/hash/generate.rb +209 -0
- data/lib/nice/hash/get_all_keys.rb +26 -0
- data/lib/nice/hash/get_values.rb +152 -0
- data/lib/nice/hash/nice_filter.rb +53 -0
- data/lib/nice/hash/pattern_fields.rb +89 -0
- data/lib/nice/hash/select_fields.rb +75 -0
- data/lib/nice/hash/select_key.rb +56 -0
- data/lib/nice/hash/set_nested.rb +54 -0
- data/lib/nice/hash/set_values.rb +99 -0
- data/lib/nice/hash/transtring.rb +32 -0
- data/lib/nice/hash/validate.rb +196 -0
- data/lib/nice_hash.rb +16 -1133
- metadata +16 -2
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
class NiceHash
|
|
2
|
+
|
|
3
|
+
##################################################
|
|
4
|
+
# Filter the hash supplied and returns only the specified keys
|
|
5
|
+
#
|
|
6
|
+
# @param hash [Hash] The hash we want to filter
|
|
7
|
+
# @param keys [Array] [Symbol] Array of symbols or symbol. Nested keys can be used: 'uno.dos.tres'
|
|
8
|
+
#
|
|
9
|
+
# @return [Hash]
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# my_hash = { user: {
|
|
13
|
+
# address: {
|
|
14
|
+
# city: 'Madrid',
|
|
15
|
+
# country: 'Spain'
|
|
16
|
+
# },
|
|
17
|
+
# name: 'Peter',
|
|
18
|
+
# age: 33,
|
|
19
|
+
# customers: [{name: 'Peter', currency: 'Euro'}, {name:'John', currency: 'Euro'}]
|
|
20
|
+
# },
|
|
21
|
+
# customer: true
|
|
22
|
+
# }
|
|
23
|
+
# NiceHash.nice_filter(my_hash, [:'user.address.city', :'customer', :'user.customers.name'])
|
|
24
|
+
# #> {:user => {:address => {:city => "Madrid"}, :customers => [{:name => "Peter"}, {:name => "John"}]}, :customer => true}
|
|
25
|
+
##################################################
|
|
26
|
+
def self.nice_filter(hash, keys)
|
|
27
|
+
result = {}
|
|
28
|
+
keys = [keys] unless keys.is_a?(Array)
|
|
29
|
+
keys.each do |k|
|
|
30
|
+
kn = k.to_s.split('.')
|
|
31
|
+
if hash.is_a?(Hash) and hash.key?(k)
|
|
32
|
+
if hash[k].is_a?(Hash)
|
|
33
|
+
result[k] = {} unless result.key?(k)
|
|
34
|
+
else
|
|
35
|
+
result[k] = hash[k]
|
|
36
|
+
end
|
|
37
|
+
elsif hash.is_a?(Hash) and hash.key?(kn.first.to_sym)
|
|
38
|
+
keys_nested = []
|
|
39
|
+
keys.grep(/^#{kn.first}\./).each do |k2|
|
|
40
|
+
keys_nested << k2.to_s.gsub(/^#{kn.first}\./,'').to_sym
|
|
41
|
+
end
|
|
42
|
+
result[kn.first.to_sym] = nice_filter(hash[kn.first.to_sym], keys_nested)
|
|
43
|
+
elsif hash.is_a?(Array)
|
|
44
|
+
result = []
|
|
45
|
+
hash.each do |a|
|
|
46
|
+
res = nice_filter(a, keys)
|
|
47
|
+
result << res unless res.empty?
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
return result
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
class NiceHash
|
|
2
|
+
|
|
3
|
+
###########################################################################
|
|
4
|
+
# It will return an array of the keys where we are using string patterns.
|
|
5
|
+
#
|
|
6
|
+
# input:
|
|
7
|
+
# pattern_hash: (Hash) Hash we want to get the pattern_fields
|
|
8
|
+
# select_hash_key: (key value) (optional) The key we want to select on the subhashes
|
|
9
|
+
# output: (Array)
|
|
10
|
+
# Array of the kind: [ [key], [key, subkey, subkey] ]
|
|
11
|
+
# Each value of the array can be used as parameter for the methods: dig, bury
|
|
12
|
+
# examples:
|
|
13
|
+
# NiceHash.pattern_fields(my_hash)
|
|
14
|
+
# #> [
|
|
15
|
+
# [:address, :correct],
|
|
16
|
+
# [:products, 0, :name],
|
|
17
|
+
# [:products, 0, :price, :correct],
|
|
18
|
+
# [:products, 1, :name],
|
|
19
|
+
# [:products, 1, :price, :correct]
|
|
20
|
+
# ]
|
|
21
|
+
# NiceHash.pattern_fields(my_hash, :correct)
|
|
22
|
+
# #> [
|
|
23
|
+
# [:address],
|
|
24
|
+
# [:products, 0, :name],
|
|
25
|
+
# [:products, 0, :price],
|
|
26
|
+
# [:products, 1, :name],
|
|
27
|
+
# [:products, 1, :price]
|
|
28
|
+
# ]
|
|
29
|
+
# Using it directly on Hash class, pattern_fields(*select_hash_key) (alias: patterns):
|
|
30
|
+
# my_hash.pattern_fields
|
|
31
|
+
# my_hash.pattern_fields(:correct)
|
|
32
|
+
# my_hash.patterns(:correct)
|
|
33
|
+
###########################################################################
|
|
34
|
+
def NiceHash.pattern_fields(pattern_hash, *select_hash_key)
|
|
35
|
+
pattern_fields = Array.new
|
|
36
|
+
|
|
37
|
+
if pattern_hash.kind_of?(Hash) and pattern_hash.size > 0
|
|
38
|
+
pattern_hash.each { |key, value|
|
|
39
|
+
key = [key]
|
|
40
|
+
if value.kind_of?(Hash)
|
|
41
|
+
if select_hash_key.size == 1 and value.keys.include?(select_hash_key[0])
|
|
42
|
+
value = value[select_hash_key[0]]
|
|
43
|
+
else
|
|
44
|
+
res = NiceHash.pattern_fields(value, *select_hash_key)
|
|
45
|
+
if res.size > 0
|
|
46
|
+
res.each { |r|
|
|
47
|
+
pattern_fields << (r.unshift(key)).flatten
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
next
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
if value.kind_of?(String)
|
|
54
|
+
if StringPattern.optimistic and value.to_s.scan(/^!?\d+-?\d*:.+/).size > 0
|
|
55
|
+
pattern_fields << key
|
|
56
|
+
end
|
|
57
|
+
elsif value.kind_of?(Symbol)
|
|
58
|
+
if value.to_s.scan(/^!?\d+-?\d*:.+/).size > 0
|
|
59
|
+
pattern_fields << key
|
|
60
|
+
end
|
|
61
|
+
elsif value.kind_of?(Array)
|
|
62
|
+
array_pattern = false
|
|
63
|
+
value.each { |v|
|
|
64
|
+
if (v.kind_of?(String) or v.kind_of?(Symbol)) and StringPattern.analyze(v, silent: true).kind_of?(StringPattern::Pattern)
|
|
65
|
+
pattern_fields << key
|
|
66
|
+
array_pattern = true
|
|
67
|
+
break
|
|
68
|
+
end
|
|
69
|
+
}
|
|
70
|
+
unless array_pattern
|
|
71
|
+
i = 0
|
|
72
|
+
value.each { |v|
|
|
73
|
+
res = NiceHash.pattern_fields(v, *select_hash_key)
|
|
74
|
+
if res.size > 0
|
|
75
|
+
res.each { |r|
|
|
76
|
+
pattern_fields << (r.unshift(i).unshift(key)).flatten
|
|
77
|
+
}
|
|
78
|
+
end
|
|
79
|
+
i += 1
|
|
80
|
+
}
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
return pattern_fields
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
class NiceHash
|
|
2
|
+
|
|
3
|
+
###########################################################################
|
|
4
|
+
# It will return an array of the keys where we are using select values of the kind: "value1|value2|value3".
|
|
5
|
+
#
|
|
6
|
+
# input:
|
|
7
|
+
# pattern_hash: (Hash) Hash we want to get the select_fields
|
|
8
|
+
# select_hash_key: (key value) (optional) The key we want to select on the subhashes
|
|
9
|
+
# output: (Array)
|
|
10
|
+
# Array of the kind: [ [key], [key, subkey, subkey] ]
|
|
11
|
+
# Each value of the array can be used as parameter for the methods: dig, bury
|
|
12
|
+
# examples:
|
|
13
|
+
# NiceHash.select_fields(my_hash)
|
|
14
|
+
# #> [[:city, :correct]]
|
|
15
|
+
# NiceHash.select_fields(my_hash, :correct)
|
|
16
|
+
# #> [[:city]]
|
|
17
|
+
# Using it directly on Hash class, select_fields(*select_hash_key):
|
|
18
|
+
# my_hash.select_fields
|
|
19
|
+
# my_hash.select_fields(:correct)
|
|
20
|
+
###########################################################################
|
|
21
|
+
def NiceHash.select_fields(pattern_hash, *select_hash_key)
|
|
22
|
+
select_fields = Array.new
|
|
23
|
+
|
|
24
|
+
if pattern_hash.kind_of?(Hash) and pattern_hash.size > 0
|
|
25
|
+
pattern_hash.each { |key, value|
|
|
26
|
+
key = [key]
|
|
27
|
+
if value.kind_of?(Hash)
|
|
28
|
+
if select_hash_key.size == 1 and value.keys.include?(select_hash_key[0])
|
|
29
|
+
value = value[select_hash_key[0]]
|
|
30
|
+
else
|
|
31
|
+
res = NiceHash.select_fields(value, *select_hash_key)
|
|
32
|
+
if res.size > 0
|
|
33
|
+
res.each { |r|
|
|
34
|
+
select_fields << (r.unshift(key)).flatten
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
next
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
if value.kind_of?(String)
|
|
41
|
+
if StringPattern.optimistic and value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size > 0
|
|
42
|
+
select_fields << key
|
|
43
|
+
end
|
|
44
|
+
elsif value.kind_of?(Symbol)
|
|
45
|
+
if value.to_s.scan(/^([\w\s\-]+\|)+[\w\s\-]+$/).size > 0
|
|
46
|
+
select_fields << key
|
|
47
|
+
end
|
|
48
|
+
elsif value.kind_of?(Array)
|
|
49
|
+
array_pattern = false
|
|
50
|
+
value.each { |v|
|
|
51
|
+
if (v.kind_of?(String) or v.kind_of?(Symbol)) and StringPattern.analyze(v, silent: true).kind_of?(StringPattern::Pattern)
|
|
52
|
+
array_pattern = true
|
|
53
|
+
break
|
|
54
|
+
end
|
|
55
|
+
}
|
|
56
|
+
unless array_pattern
|
|
57
|
+
i = 0
|
|
58
|
+
value.each { |v|
|
|
59
|
+
res = NiceHash.select_fields(v, *select_hash_key)
|
|
60
|
+
if res.size > 0
|
|
61
|
+
res.each { |r|
|
|
62
|
+
select_fields << (r.unshift(i).unshift(key)).flatten
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
i += 1
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
}
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
return select_fields
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class NiceHash
|
|
2
|
+
###########################################################################
|
|
3
|
+
# It will filter the hash by the key specified on select_hash_key.
|
|
4
|
+
# In case a subhash specified on a value it will be selected only the value of the key specified on select_hash_key
|
|
5
|
+
#
|
|
6
|
+
# input:
|
|
7
|
+
# pattern_hash: (Hash) Hash we want to select specific keys
|
|
8
|
+
# select_hash_key: (key value) The key we want to select on the subhashes
|
|
9
|
+
# output: (Hash)
|
|
10
|
+
# The same hash but in case a subhash specified on a value it will be selected only the value of the key specified on select_hash_key
|
|
11
|
+
# example:
|
|
12
|
+
# new_hash = NiceHash.select_key(my_hash, :wrong)
|
|
13
|
+
# #> {:name=>"Peter", :address=>"\#$$$$$", :city=>"Germany", :products=> [{:name=>:"10:Ln", :price=>"-20"}, {:name=>:"10:Ln", :price=>"-20"}]}
|
|
14
|
+
# Using it directly on Hash class, select_key(select_hash_key):
|
|
15
|
+
# new_hash = my_hash.select_key(:wrong)
|
|
16
|
+
###########################################################################
|
|
17
|
+
def NiceHash.select_key(pattern_hash, select_hash_key)
|
|
18
|
+
hashv = Hash.new()
|
|
19
|
+
|
|
20
|
+
if pattern_hash.kind_of?(Hash) and pattern_hash.size > 0
|
|
21
|
+
pattern_hash.each { |key, value|
|
|
22
|
+
if value.kind_of?(Hash)
|
|
23
|
+
if value.keys.include?(select_hash_key)
|
|
24
|
+
value = value[select_hash_key]
|
|
25
|
+
else
|
|
26
|
+
value = NiceHash.select_key(value, select_hash_key)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
if value.kind_of?(Array)
|
|
30
|
+
array_pattern = false
|
|
31
|
+
value.each { |v|
|
|
32
|
+
if (v.kind_of?(String) or v.kind_of?(Symbol)) and StringPattern.analyze(v, silent: true).kind_of?(StringPattern::Pattern)
|
|
33
|
+
hashv[key] = value
|
|
34
|
+
array_pattern = true
|
|
35
|
+
break
|
|
36
|
+
end
|
|
37
|
+
}
|
|
38
|
+
unless array_pattern
|
|
39
|
+
value_ret = Array.new
|
|
40
|
+
value.each { |v|
|
|
41
|
+
ret = NiceHash.select_key(v, select_hash_key)
|
|
42
|
+
value_ret << ret
|
|
43
|
+
}
|
|
44
|
+
hashv[key] = value_ret
|
|
45
|
+
end
|
|
46
|
+
else
|
|
47
|
+
hashv[key] = value
|
|
48
|
+
end
|
|
49
|
+
}
|
|
50
|
+
else
|
|
51
|
+
return pattern_hash
|
|
52
|
+
end
|
|
53
|
+
return hashv
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
class NiceHash
|
|
2
|
+
##################################################
|
|
3
|
+
# sets the supplied value on the supplied nested key
|
|
4
|
+
#
|
|
5
|
+
# @param hash [Hash] The hash we want
|
|
6
|
+
# @param nested_key [Hash] [String] String with the nested key: 'uno.dos.tres' or a hash { uno: {dos: :tres} }
|
|
7
|
+
# @param value [] value to set
|
|
8
|
+
#
|
|
9
|
+
# @return [Hash]
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# my_hash = { user: {
|
|
13
|
+
# address: {
|
|
14
|
+
# city: 'Madrid',
|
|
15
|
+
# country: 'Spain'
|
|
16
|
+
# },
|
|
17
|
+
# name: 'Peter',
|
|
18
|
+
# age: 33
|
|
19
|
+
# },
|
|
20
|
+
# customer: true
|
|
21
|
+
# }
|
|
22
|
+
# NiceHash.set_nested(my_hash, 'user.address.city', 'Barcelona')
|
|
23
|
+
# #>{:user=>{:address=>{:city=>'Barcelona', :country=>"Spain"}, :name=>"Peter", :age=>33}, :customer=>true}
|
|
24
|
+
##################################################
|
|
25
|
+
def self.set_nested(hash, nested_key, value, only_if_exist = false)
|
|
26
|
+
nested_key = transtring(nested_key)
|
|
27
|
+
keys = nested_key.split(".")
|
|
28
|
+
if keys.size == 1
|
|
29
|
+
hash[nested_key.to_sym] = value unless only_if_exist and !hash.key?(nested_key.to_sym)
|
|
30
|
+
else
|
|
31
|
+
exist = true
|
|
32
|
+
if only_if_exist
|
|
33
|
+
ht = hash.deep_copy
|
|
34
|
+
keys.each do |k|
|
|
35
|
+
unless ht.key?(k.to_sym)
|
|
36
|
+
exist = false
|
|
37
|
+
break
|
|
38
|
+
end
|
|
39
|
+
ht = ht[k.to_sym]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
if !only_if_exist or (only_if_exist and exist)
|
|
43
|
+
if value.is_a?(String)
|
|
44
|
+
eval("hash.#{nested_key}='#{value}'")
|
|
45
|
+
else
|
|
46
|
+
#todo: consider other kind of objects apart of strings
|
|
47
|
+
eval("hash.#{nested_key}=#{value}")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
return hash
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
class NiceHash
|
|
2
|
+
###########################################################################
|
|
3
|
+
# It will search for the keys supplied and it will set the value specified
|
|
4
|
+
#
|
|
5
|
+
# input:
|
|
6
|
+
# hash_array: (Hash/Array) Hash/Array we want to search on
|
|
7
|
+
# hash_values: (Hash) Hash that contains the keys and values to set
|
|
8
|
+
# output: (Hash/Array)
|
|
9
|
+
# The same hash/array but with the values we specifed changed
|
|
10
|
+
# example:
|
|
11
|
+
# new_hash = NiceHash.set_values(my_hash, {city: 'London', price: '1000'})
|
|
12
|
+
# #> {:name=>"Peter", :address=>"\#$$$$$", :city=>"London", :products=> [{:name=>:"10:Ln", :price=>"1000"}, {:name=>:"10:Ln", :price=>"1000"}]}
|
|
13
|
+
# Using it directly on Hash class, set_values(hash_values):
|
|
14
|
+
# new_hash = my_hash.set_values({city: 'London', price: '1000'})
|
|
15
|
+
# Setting specific nested keys
|
|
16
|
+
# new_hash = my_hash.set_values({'data.lab.products.price': 75, 'data.lab.beep': false})
|
|
17
|
+
###########################################################################
|
|
18
|
+
def NiceHash.set_values(hash_array, hash_values)
|
|
19
|
+
hashv = Hash.new()
|
|
20
|
+
if hash_array.is_a?(Hash) and hash_array.size > 0
|
|
21
|
+
#for the case same_values on hash_values
|
|
22
|
+
#fex: ({pwd1: 'aaaa', pwd2: 'bbbbb', uno: 1}).set_values({[:pwd1, :pwd2]=>:'1-10:n'})
|
|
23
|
+
# should return : {[:pwd1, :pwd2]=>:'1-10:n', uno: 1}
|
|
24
|
+
#todo: it doesn't work for all cases, just simple one
|
|
25
|
+
if hash_values.is_a?(Hash) and hash_values.keys.flatten.size != hash_values.keys.size
|
|
26
|
+
hash_values.each do |k,v|
|
|
27
|
+
if k.is_a?(Array)
|
|
28
|
+
k.each do |kvk|
|
|
29
|
+
if hash_array.key?(kvk)
|
|
30
|
+
hash_array[kvk] = hash_values[k]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
hash_array.each do |k, v|
|
|
38
|
+
#for the case of using same_values: [:pwd1, :pwd2] => :'10:N' and supply hash_values: pwd1: 'a', pwd2: 'b'
|
|
39
|
+
#instead of [:pwd1,:pwd2]=>'a'
|
|
40
|
+
same_values_key_done = false
|
|
41
|
+
if k.is_a?(Array)
|
|
42
|
+
#todo: we are treating here only a simple case, consider to add also nested keys, array of values...
|
|
43
|
+
k.each do |kvk|
|
|
44
|
+
if hash_values.keys.include?(kvk)
|
|
45
|
+
hashv[k] = hash_values[kvk]
|
|
46
|
+
same_values_key_done = true
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
unless same_values_key_done
|
|
51
|
+
if hash_values.keys.include?(k)
|
|
52
|
+
hashv[k] = hash_values[k]
|
|
53
|
+
elsif v.is_a?(Array)
|
|
54
|
+
if hash_values.has_rkey?('\.') # the kind of 'uno.dos.tres'
|
|
55
|
+
new_hash_values = {}
|
|
56
|
+
hash_values.each do |kk,vv|
|
|
57
|
+
if kk.to_s.match?(/^#{k}\./)
|
|
58
|
+
kk = kk.to_s.gsub(/^#{k}\./, '').to_sym
|
|
59
|
+
new_hash_values[kk] = vv
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
hashv[k] = NiceHash.set_values(v, new_hash_values)
|
|
63
|
+
else
|
|
64
|
+
hashv[k] = NiceHash.set_values(v, hash_values)
|
|
65
|
+
end
|
|
66
|
+
elsif v.is_a?(Hash)
|
|
67
|
+
if hash_values.has_rkey?('\.') # the kind of 'uno.dos.tres'
|
|
68
|
+
new_hash_values = {}
|
|
69
|
+
hash_values.each do |kk,vv|
|
|
70
|
+
if kk.to_s.match?(/^#{k}\./)
|
|
71
|
+
kk = kk.to_s.gsub(/^#{k}\./, '').to_sym
|
|
72
|
+
new_hash_values[kk] = vv
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
hashv[k] = NiceHash.set_values(v, new_hash_values)
|
|
76
|
+
else
|
|
77
|
+
hashv[k] = NiceHash.set_values(v, hash_values)
|
|
78
|
+
end
|
|
79
|
+
else
|
|
80
|
+
hashv[k] = v
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
hash_values.each do |k, v|
|
|
85
|
+
hashv = NiceHash.set_nested(hashv, k, v, true) if k.is_a?(Hash)
|
|
86
|
+
end
|
|
87
|
+
return hashv
|
|
88
|
+
elsif hash_array.is_a?(Array) and hash_array.size > 0
|
|
89
|
+
hashv = Array.new
|
|
90
|
+
hash_array.each do |r|
|
|
91
|
+
hashv << NiceHash.set_values(r, hash_values)
|
|
92
|
+
end
|
|
93
|
+
return hashv
|
|
94
|
+
else
|
|
95
|
+
return hash_array
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class NiceHash
|
|
2
|
+
##################################################
|
|
3
|
+
# Translate a hash of hashes into a string separted by .
|
|
4
|
+
#
|
|
5
|
+
# @param hash [Hash] The hash we want to translate
|
|
6
|
+
#
|
|
7
|
+
# @return [String]
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# my_hash = { uno: {dos: :tres} }
|
|
11
|
+
# NiceHash.transtring(my_hash)
|
|
12
|
+
# #>"uno.dos.tres"
|
|
13
|
+
##################################################
|
|
14
|
+
def self.transtring(hash)
|
|
15
|
+
keys = []
|
|
16
|
+
if hash.is_a?(Hash)
|
|
17
|
+
hash.each do |k, v|
|
|
18
|
+
if v.is_a?(Hash)
|
|
19
|
+
keys << k
|
|
20
|
+
keys << transtring(v)
|
|
21
|
+
else
|
|
22
|
+
keys << k
|
|
23
|
+
keys << v
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
keys << hash
|
|
28
|
+
end
|
|
29
|
+
return keys.join(".")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|