-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnormalize_key.rb
129 lines (99 loc) · 2.27 KB
/
normalize_key.rb
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# ~/lib/ruby/normalize_key.rb
#
# From: alphavantage gem
#
# TODO: Refactor this into a reusable component
#
# Convert a hash key to a snake_case symbol
#
class NormalizeKey
def initialize(key:)
@key = key
end
def call
return @key if is_date?(@key)
underscore_key(sanitize_key(@key))
end
private
def underscore_key(key)
key.to_s.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase.to_sym
end
def sanitize_key(key)
key.tr('.():/','').gsub(/^\d+.?\s/, "").tr(' ','_')
end
def is_date?(key)
!/(\d{4}-\d{2}-\d{2})/.match(key.to_s).nil?
end
end
def convert_hash_keys(value)
case value
when Array
value.map { |v| convert_hash_keys(v) }
when Hash
Hash[value.map { |k, v| [ NormalizeKey.new(key: k).call, convert_hash_keys(v) ] }]
else
value
end
end
__END__
# First cut at a refactor, AI generated ...
class Hash
def sanitize_keys
self.transform_keys { |k| sanitize_key(k) }
end
def convert_keys
self.transform_keys { |k| convert_key(k) }
end
def normalize_keys
self.transform_keys { |k| normalize_key(k) }
end
private
def sanitize_key(key)
key.tr('.():/','').gsub(/^\d+.?\s/, "").tr(' ','_')
end
def convert_key(key)
key.to_s.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase.to_sym
end
def normalize_key(key)
return key if is_date?(key)
underscore_key(sanitize_key(key))
end
def underscore_key(key)
key.to_s.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase.to_sym
end
def is_date?(key)
!/(\d{4}-\d{2}-\d{2})/.match(key.to_s).nil?
end
end
# Example usage
hash = {
"HelloWorld" => "value",
"foo.bar" => {
"Baz" => 123
}
}
sanitized_hash = hash.sanitize_keys
converted_hash = hash.convert_keys
normalized_hash = hash.normalize_keys
puts sanitized_hash
puts converted_hash
puts normalized_hash
Output:
santized ...
{ "HelloWorld" => "value", "foobar" => { "Baz" => 123 } }
converted ...
{ "hello_world" => "value", "foo_bar" => { "baz" => 123 } }
normalized ...
{ :hello_world => "value", :foo_bar => { :baz => 123 } }