nested_hash 0.0.1
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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +36 -0
- data/Rakefile +5 -0
- data/lib/nested_hash.rb +74 -0
- data/lib/nested_hash/version.rb +3 -0
- data/nested_hash.gemspec +20 -0
- data/test/test_simple_to_complex_hash.rb +34 -0
- metadata +55 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# NestedHash
|
2
|
+
|
3
|
+
|
4
|
+
NestedHash is a Hash converter. It will created a simple, key encoded hash, in to a nested hash. For example, the hash:
|
5
|
+
|
6
|
+
```ruby
|
7
|
+
{ "name" => "guillermo", "properties.age" => 29, "properties.sex" => "male", "parents.1" => "ramon", "parents.2" => "gloria" }
|
8
|
+
```
|
9
|
+
|
10
|
+
into the hash
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
{ "name" => "guillermo", "properties" => {"age" => 29, "sex" => "male"}, "parents" => [ "ramon", "gloria" ] }
|
14
|
+
```
|
15
|
+
|
16
|
+
# Usage
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
require 'nested_hash'
|
20
|
+
|
21
|
+
my_normal_hash = { "name" => "guillermo", "properties.age" => 29, "properties.sex" => "male", "parents.1" => "ramon", "parents.2" => "gloria" }
|
22
|
+
|
23
|
+
my_new_hash = NestedHash.new(my_normal_hash)
|
24
|
+
|
25
|
+
|
26
|
+
# Motivations
|
27
|
+
|
28
|
+
The reason for creating this ruby gem is to convert Excel files to json files. With the rubygems roo you already can get the rows into a one level hash (colum title as a key). This complement help to create more difficult structures with the same excel file.
|
29
|
+
|
30
|
+
# Todo
|
31
|
+
|
32
|
+
* Add support for properties in arrays
|
33
|
+
|
34
|
+
# License
|
35
|
+
|
36
|
+
Mit
|
data/Rakefile
ADDED
data/lib/nested_hash.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require "nested_hash/version"
|
2
|
+
|
3
|
+
class NestedHash < Hash
|
4
|
+
|
5
|
+
def initialize(hash = {})
|
6
|
+
hash.each do |key,v|
|
7
|
+
key = sanitize_key(key)
|
8
|
+
|
9
|
+
if is_valid_key?(key)
|
10
|
+
process(key,v)
|
11
|
+
elsif copy_invalid_keys?
|
12
|
+
copy(key,v)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def copy_invalid_keys?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def sanitize_key(key)
|
24
|
+
key
|
25
|
+
end
|
26
|
+
|
27
|
+
def is_valid_key?(key)
|
28
|
+
key.is_a?(String) && key =~ /\A[\.\w]+\z/
|
29
|
+
end
|
30
|
+
|
31
|
+
def copy(key,value)
|
32
|
+
self[key] = value
|
33
|
+
end
|
34
|
+
|
35
|
+
def process(key,value)
|
36
|
+
if key =~ /\./
|
37
|
+
process_nested(key,value)
|
38
|
+
else
|
39
|
+
self[key] = value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def sanitize_value(v)
|
45
|
+
v
|
46
|
+
end
|
47
|
+
|
48
|
+
def process_nested(key, value)
|
49
|
+
keys = key.split(".")
|
50
|
+
previous = keys.shift
|
51
|
+
top = keys.inject(self) do |memo,key|
|
52
|
+
if is_for_array?(key)
|
53
|
+
memo[previous] ||= []
|
54
|
+
else
|
55
|
+
memo[previous] ||= {}
|
56
|
+
end
|
57
|
+
a = memo[previous]
|
58
|
+
previous = key
|
59
|
+
a
|
60
|
+
end
|
61
|
+
|
62
|
+
if top.is_a?(Array)
|
63
|
+
top << value
|
64
|
+
else
|
65
|
+
top[previous] = value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def is_for_array?(key)
|
70
|
+
key =~ /\A\d+\z/
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end
|
data/nested_hash.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "nested_hash/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "nested_hash"
|
7
|
+
s.version = NestedHash::VERSION
|
8
|
+
s.authors = ["Guillermo Álvarez"]
|
9
|
+
s.email = ["guillermo@cientifico.net"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Convert a simple one level hash to a multilevel hash}
|
12
|
+
s.description = %q{For example a hash like { "properties.age" => 3 } will be converted into { "properties" => {"age" => 3}} }
|
13
|
+
|
14
|
+
s.rubyforge_project = "nested_hash"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'nested_hash'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class NestedHashTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_class
|
7
|
+
nested_hash = NestedHash.new
|
8
|
+
nested_hash.is_a?(Hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_true
|
12
|
+
assert true
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_subitem_conversion
|
16
|
+
initial = { "properties.age" => 3 }
|
17
|
+
final = { "properties" => { "age" => 3 }}
|
18
|
+
hash = NestedHash.new(initial)
|
19
|
+
assert_equal 1, hash.keys.size
|
20
|
+
assert_equal ['properties'], hash.keys
|
21
|
+
assert_equal ['age'], hash['properties'].keys
|
22
|
+
assert_equal 3, hash['properties']['age']
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_array_subitem
|
26
|
+
initial = { 'child.1' => 'pepe', "child.2" => 'juan'}
|
27
|
+
final = { 'child' => [ 'pepe', 'juan']}
|
28
|
+
hash = NestedHash.new(initial)
|
29
|
+
|
30
|
+
assert_equal 1, hash.keys.size
|
31
|
+
assert_equal ['child'], hash.keys
|
32
|
+
assert_equal ['pepe','juan'], hash["child"]
|
33
|
+
end
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nested_hash
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Guillermo Álvarez
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-24 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! 'For example a hash like { "properties.age" => 3 } will be converted
|
15
|
+
into { "properties" => {"age" => 3}} '
|
16
|
+
email:
|
17
|
+
- guillermo@cientifico.net
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- Gemfile
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- lib/nested_hash.rb
|
27
|
+
- lib/nested_hash/version.rb
|
28
|
+
- nested_hash.gemspec
|
29
|
+
- test/test_simple_to_complex_hash.rb
|
30
|
+
homepage: ''
|
31
|
+
licenses: []
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project: nested_hash
|
50
|
+
rubygems_version: 1.8.16
|
51
|
+
signing_key:
|
52
|
+
specification_version: 3
|
53
|
+
summary: Convert a simple one level hash to a multilevel hash
|
54
|
+
test_files:
|
55
|
+
- test/test_simple_to_complex_hash.rb
|