Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

deep-hash-struct

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

deep-hash-struct

  • 0.1.6
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

Deep::Hash::Struct

Struct copes with the operation that is Deep. Because the data maintenance of many hierarchies became possible, I can treat it like Hash.

Installation

Add this line to your application's Gemfile:

gem 'deep-hash-struct'

And then execute:

$ bundle

Or install it yourself as:

$ gem install deep-hash-struct

Supported Ruby Versions

  • 2.5.0
  • 2.4.1
  • 2.3.1

Wrapper Class Usage

The basic usage is the same as Hash Class.

Basic

wrapper         = Deep::Hash::Struct::Wrapper.new
wrapper.a       = 1
wrapper.b.a     = 2
wrapper[:c][:a] = 3
wrapper[:c].b   = 4
wrapper.to_h # => {:a=>1, :b=>{:a=>2}, :c=>{:a=>3, :b=>4}}

Block

wrapper.a do
  1 + 1
end
wrapper.a # => 2

wrapper.b do
  { c: 3 }
end
wrapper.b.c # => 3

#dig

wrapper.a.b = { c: 1, d: [1, 2, [3, 4, 5]] }
wrapper.dig(:a, :b, :c)       # => 1
wrapper.dig(:a, :b, :d, 2, 0) # => 3
wrapper.dig(:a, :c).blank?    # => true

#merge

Deep::Hash::Struct::Wrapper Class
wrapper.a   = 1
wrapper.b   = 2
wrapper.c.a = 3
wrapper.c.b = 4
wrapper.c.c = 5

other       = wrapper.class.new
other.a     = 6
other.b     = 7
other.c.a   = 8

wrapper.merge(other).to_h # => {:a=>6, :b=>7, :c=>{:a=>8}}
Hash Class
wrapper.a     = 1
wrapper.b     = 2
wrapper.c.a   = 3
wrapper.c.b   = 4
wrapper.c.c   = 5

other         = {}
other[:a]     = 6
other[:b]     = 7
other[:c]     = {}
other[:c][:a] = 8

wrapper.merge(other).to_h #=> {:a=>6, :b=>7, :c=>{:a=>8}}

#merge! #update

bang merge method

#deep_merge

Deep::Hash::Struct::Wrapper Class
wrapper.a   = 1
wrapper.b   = 2
wrapper.c.a = 3
wrapper.c.b = 4
wrapper.c.c = 5

other       = wrapper.class.new
other.a     = 6
other.b     = 7
other.c.a   = 8

wrapper.deep_merge(other).to_h # => {:a=>6, :b=>7, :c=>{:a=>8, :b=>4, :c=>5}}
Hash Class
wrapper.a     = 1
wrapper.b     = 2
wrapper.c.a   = 3
wrapper.c.b   = 4
wrapper.c.c   = 5

other         = {}
other[:a]     = 6
other[:b]     = 7
other[:c]     = {}
other[:c][:a] = 8

wrapper.deep_merge(other).to_h # => {:a=>6, :b=>7, :c=>{:a=>8, :b=>4, :c=>5}}

#deep_merge!

bang deep_merge method

#reverse_merge

Deep::Hash::Struct::Wrapper Class
wrapper.a   = 1
wrapper.b   = 2
wrapper.c.a = 3
wrapper.c.b = 4
wrapper.c.c = 5

other       = wrapper.class.new
other.a     = 6
other.b     = 7
other.c.a   = 8
other.d.a   = 9

wrapper.reverse_merge(other).to_h # => {:a=>1, :b=>2, :c=>{:a=>3, :b=>4, :c=>5}, :d=>{:a=>9}}
Hash Class
wrapper.a     = 1
wrapper.b     = 2
wrapper.c.a   = 3
wrapper.c.b   = 4
wrapper.c.c   = 5

other         = {}
other[:a]     = 6
other[:b]     = 7
other[:c]     = {}
other[:c][:a] = 8
other[:d]     = {}
other[:d][:a] = 9

wrapper.reverse_merge(other).to_h # => {:a=>1, :b=>2, :c=>{:a=>3, :b=>4, :c=>5}, :d=>{:a=>9}}

#reverse_merge!

bang reverse_merge method

#reverse_deep_merge

Deep::Hash::Struct::Wrapper Class
wrapper.a   = 1
wrapper.b   = 2
wrapper.c.a = 3
wrapper.c.b = 4
wrapper.c.c = 5

other       = wrapper.class.new
other.a     = 6
other.b     = 7
other.c.a   = 8
other.c.d   = 9

wrapper.reverse_deep_merge(other).to_h # => {:a=>1, :b=>2, :c=>{:a=>3, :b=>4, :c=>5, :d=>9}}
Hash Class
wrapper.a     = 1
wrapper.b     = 2
wrapper.c.a   = 3
wrapper.c.b   = 4
wrapper.c.c   = 5

other         = {}
other[:a]     = 6
other[:b]     = 7
other[:c]     = {}
other[:c][:a] = 8
other[:c][:d] = 9

wrapper.reverse_deep_merge(other).to_h # => {:a=>1, :b=>2, :c=>{:a=>3, :b=>4, :c=>5, :d=>9}}

#reverse_deep_merge!

bang reverse_deep_merge method

#fetch

wrapper.a = 1
wrapper.fetch(:a, :not_found)              # => 1
wrapper.fetch(:a) { |k| "#{k} not found" } # => 1
wrapper.fetch(:b)                          # => nil
wrapper.fetch(:b, :not_found)              # => :not_found
wrapper.fetch(:b) { |k| "#{k} not found" } # => "b not found"

#default

wrapper.a.default = 0
wrapper.b.default = []
wrapper.a.a # => 0
wrapper.b.a # => []

#map_key

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3
wrapper.map_key { |k| [k] } # => [[:a], [:b], [:c]]

#map_value

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3
wrapper.map_value { |k| [k] } # => [[1], [2], [3]]

#fetch_values

wrapper.a = 1
wrapper.b = 2
wrapper.fetch_values(:a, :b)                  # => [1, 2]
wrapper.fetch_values(:a, :c)                  # => KeyError: key not found: :c
wrapper.fetch_values(:a, :c) { |k| k.upcase } # => [1, :C]

#values_at

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3
wrapper.values_at(:a, :b, :d) # => [1, 2, nil]

#invert

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3
wrapper.invert # => {1=>:a, 2=>:b, 3=>:c}

#delete

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3
wrapper.delete(:a) # => 1
wrapper.keys       # => [:b, :c]

#delete_if

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3
wrapper.delete_if{ |k, v| k == :a || v == 2 }.to_h # => {:c=>3}
wrapper.keys                                       # => [:c]

#reject

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3
wrapper.reject { |k, v| v > 2 }.to_h # => {:a=>1, :b=>2}

#reject!

bang reject method

#clear

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3
wrapper.clear
wrapper.to_h # => {}

#flatten

wrapper.a   = 1
wrapper.b   = 2
wrapper.c.a = 3
wrapper.c.b = 4
wrapper.c.c = 5
wrapper.flatten # => [:a, 1, :b, 2, :c, {:a=>3, :b=>4, :c=>5}]

#has_key? #include?

wrapper.a = 1
wrapper.has_key?(:a) # => true
wrapper.has_key?(:b) # => false

#has_keys?

wrapper.a   = 1
wrapper.b   = 2
wrapper.c.a = 3
wrapper.has_keys?(:a)     # => true
wrapper.has_keys?(:c, :a) # => true
wrapper.has_keys?(:d)     # => false
wrapper.has_keys?(:c, :b) # => false
wrapper.has_keys?(:d, :a) # => false

#exclude?

wrapper.a = 1
wrapper.exclude?(:a) # => false
wrapper.exclude?(:d) # => true

#sort

wrapper.c = 1
wrapper.b = 2
wrapper.a = 3
wrapper.sort # => [[:a, 3], [:b, 2], [:c, 1]]

#shift

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3
wrapper.shift # => [:a, 1]
wrapper.to_h  # => {:b=>2, :c=>3}

#compact

wrapper.a   = 1
wrapper.b   = nil
wrapper.c.a = 2
wrapper.c.b = ""
wrapper.d.a = nil

wrapper.keys           # => [:a, :b, :c, :d]
wrapper.c.keys         # => [:a, :b]
wrapper.compact.keys   # => [:a, :c, :d]
wrapper.compact.c.keys # => [:a, :b]
wrapper.keys           # => [:a, :b, :c, :d]
wrapper.c.keys         # => [:a, :b]

#compact!

bang compact method

#deep_compact

wrapper.a   = 1
wrapper.b   = nil
wrapper.c.a = 2
wrapper.c.b = ""
wrapper.d.a = nil

wrapper.keys                # => [:a, :b, :c, :d]
wrapper.c.keys              # => [:a, :b]
wrapper.deep_compact.keys   # => [:a, :c]
wrapper.deep_compact.c.keys # => [:a, :b]
wrapper.keys                # => [:a, :b, :c, :d]
wrapper.c.keys              # => [:a, :b]

#deep_compact!

bang deep_compact method

#slice

wrapper.a = 1
wrapper.b = 2
wrapper.c = 3

wrapper.slice(:a, :b).to_h # => {:a=>1, :b=>2}
wrapper.slice(:b, :c).to_h # => {:b=>2, :c=>3}
wrapper.slice(:c, :d).to_h # => {:c=>3}
wrapper.to_h               # => {:a=>1, :b=>2, :c=>3}

#slice!

bang slice method

#to_hash #to_h

wrapper.a   = 1
wrapper.b   = 2
wrapper.c.a = 3

wrapper.to_hash # => {:a=>1, :b=>2, :c=>{:a=>3}}

#to_json

wrapper.a   = 1
wrapper.b   = 2
wrapper.c.a = 3
wrapper.to_json # => "{\"a\":1,\"b\":2,\"c\":{\"a\":3}}"

#max_stages

wrapper.a     = 1
wrapper.b.a   = 2
wrapper.b.b   = 3
wrapper.c.a.b = 4
wrapper.c.a.c = 5
wrapper.c.a.d = 6

wrapper.max_stages   # => 3
wrapper.b.max_stages # => 1
wrapper.c.max_stages # => 2

#min_stages

wrapper.a     = 1
wrapper.b.a   = 2
wrapper.b.b   = 3
wrapper.c.a.b = 4
wrapper.c.a.c = 5
wrapper.c.a.d = 6

wrapper.min_stages   # => 1
wrapper.b.min_stages # => 1
wrapper.c.min_stages # => 2

Dashboard Class Usage

It is used like a two-dimensional array representing a table.

Add matrix table

dashboard = Deep::Hash::Struct::Dashboard.new
dashboard.add_table(matrix: true, side_header: "sh") do |t|
  t.add_header do |h|
    h.a   = "h1"
    h[:b] = "h2"
    h.add :c, "h3"
  end

  t.add_side do |s|
    s.a   = "s1"
    s[:b] = "s2"
    s.add :c, "s3"
  end

  t.add_body do |row|
    row.a.a     = 11
    row.a[:b]   = 12
    row[:a][:c] = 13
    row[:b].a   = 14
    row.b.add :b, 15
    row.b.c     = 16
    row.c.a     = 17
    row.c.b     = 18
    row.c.c     = 19
  end
end

dashboard.tables # => [#<Table matrix=true>]

table = "<table>\n"
dashboard.tables[0].each do |rows|
  table << "  <tr>\n"
  rows.each do |row|
    if row.side_or_header?
      table << "    <th>#{row.name}</th>\n"
    else
      table << "    <td>#{row.value}</td>\n"
    end
  end
  table << "  </tr>\n"
end
table << "</table>\n"

puts table
# => <table>
# =>   <tr>
# =>     <th>sh</th>
# =>     <th>h1</th>
# =>     <th>h2</th>
# =>     <th>h3</th>
# =>   </tr>
# =>   <tr>
# =>     <th>s1</th>
# =>     <td>11</td>
# =>     <td>14</td>
# =>     <td>17</td>
# =>   </tr>
# =>   <tr>
# =>     <th>s2</th>
# =>     <td>12</td>
# =>     <td>15</td>
# =>     <td>18</td>
# =>   </tr>
# =>   <tr>
# =>     <th>s3</th>
# =>     <td>13</td>
# =>     <td>16</td>
# =>     <td>19</td>
# =>   </tr>
# => </table>

Add segment table

dashboard = Deep::Hash::Struct::Dashboard.new
dashboard.add_table do |t|
  t.add_header do |h|
    h.a   = "h1"
    h[:b] = "h2"
    h.add :c, "h3"
  end

  t.add_body do |row|
    row.a = 11
    row.b = 12
    row.c = 13
  end

  t.add_body do |row|
    row.c = 16
    row.b = 15
    row.a = 14
  end

  t.add_body do |row|
    row.c = 19
    row.a = 17
    row.b = 18
  end
end

dashboard.tables # => [#<Table matrix=false>]

table = "<table>\n"
dashboard.tables[0].each do |rows|
  table << "  <tr>\n"
  rows.each do |row|
    if row.header?
      table << "    <th>#{row.name}</th>\n"
    else
      table << "    <td>#{row.value}</td>\n"
    end
  end
  table << "  </tr>\n"
end
table << "</table>\n"

puts table
# => <table>
# =>   <tr>
# =>     <th>h1</th>
# =>     <th>h2</th>
# =>     <th>h3</th>
# =>   </tr>
# =>   <tr>
# =>     <td>11</td>
# =>     <td>12</td>
# =>     <td>13</td>
# =>   </tr>
# =>   <tr>
# =>     <td>14</td>
# =>     <td>15</td>
# =>     <td>16</td>
# =>   </tr>
# =>   <tr>
# =>     <td>17</td>
# =>     <td>18</td>
# =>     <td>19</td>
# =>   </tr>
# => </table>

Unset value to matrix table

dashboard = Deep::Hash::Struct::Dashboard.new
dashboard.add_table(matrix: true) do |t|
  t.add_header do |h|
    h.a   = "h1"
    h[:b] = "h2"
    h.add :c, "h3"
  end

  t.add_side do |s|
    s.a   = "s1"
    s[:b] = "s2"
    s.add :c, "s3"
  end

  t.add_body do |row|
    row.a.b = 2
    row.a.c = 3
    row.b.a = 4
    row.b.c = 6
    row.c.a = 7
    row.c.b = 8
  end
end

dashboard.tables # => [#<Table matrix=true>]

table = "<table>\n"
dashboard.tables[0].each do |rows|
  table << "  <tr>\n"
  rows.each do |row|
    if row.side_or_header?
      table << "    <th>#{row.name}</th>\n"
    else
      table << "    <td>#{row.value}</td>\n"
    end
  end
  table << "  </tr>\n"
end
table << "</table>\n"

puts table
# => <table>
# =>  <tr>
# =>    <th></th>
# =>    <th>h1</th>
# =>    <th>h2</th>
# =>    <th>h3</th>
# =>  </tr>
# =>  <tr>
# =>    <th>s1</th>
# =>    <td></td>
# =>    <td>4</td>
# =>    <td>7</td>
# =>  </tr>
# =>  <tr>
# =>    <th>s2</th>
# =>    <td>2</td>
# =>    <td></td>
# =>    <td>8</td>
# =>  </tr>
# =>  <tr>
# =>    <th>s3</th>
# =>    <td>3</td>
# =>    <td>6</td>
# =>    <td></td>
# =>  </tr>
# =></table>

Unset value to segment table

dashboard = Deep::Hash::Struct::Dashboard.new
dashboard.add_table do |t|
  t.add_header do |h|
    h.a = "h1"
    h.b = "h2"
    h.c = "h3"
  end

  t.add_body do |row|
    row.b = 2
    row.c = 3
  end

  t.add_body do |row|
    row.a = 4
    row.c = 6
  end

  t.add_body do |row|
    row.a = 7
    row.b = 8
  end
end

dashboard.tables # => [#<Table matrix=false>]

table = "<table>\n"
dashboard.tables[0].each do |rows|
  table << "  <tr>\n"
  rows.each do |row|
    if row.header?
      table << "    <th>#{row.name}</th>\n"
    else
      table << "    <td>#{row.value}</td>\n"
    end
  end
  table << "  </tr>\n"
end
table << "</table>\n"

puts table
# => <table>
# =>   <tr>
# =>     <th>h1</th>
# =>     <th>h2</th>
# =>     <th>h3</th>
# =>   </tr>
# =>   <tr>
# =>     <td></td>
# =>     <td>2</td>
# =>     <td>3</td>
# =>   </tr>
# =>   <tr>
# =>     <td>4</td>
# =>     <td></td>
# =>     <td>6</td>
# =>   </tr>
# =>   <tr>
# =>     <td>7</td>
# =>     <td>8</td>
# =>     <td></td>
# =>   </tr>
# => </table>

Default to matrix table

dashboard = Deep::Hash::Struct::Dashboard.new
dashboard.add_table(matrix: true, default: 0) do |t|
  t.add_header do |h|
    h.a = "h1"
    h.b = "h2"
    h.c = "h3"
  end

  t.add_side do |s|
    s.a = "s1"
    s.b = "s2"
    s.c = "s3"
  end

  t.add_body do |row|
    row.a.b = 2
    row.a.c = 3
    row.b.a = 4
    row.b.c = 6
    row.c.a = 7
    row.c.b = 8
  end
end

dashboard.tables # => [#<Table matrix=true>]

table = "<table>\n"
dashboard.tables[0].each do |rows|
  table << "  <tr>\n"
  rows.each do |row|
    if row.side_or_header?
      table << "    <th>#{row.name}</th>\n"
    else
      table << "    <td>#{row.value}</td>\n"
    end
  end
  table << "  </tr>\n"
end
table << "</table>\n"

puts table
# => <table>
# =>   <tr>
# =>     <th></th>
# =>     <th>h1</th>
# =>     <th>h2</th>
# =>     <th>h3</th>
# =>   </tr>
# =>   <tr>
# =>     <th>s1</th>
# =>     <td>0</td>
# =>     <td>4</td>
# =>     <td>7</td>
# =>   </tr>
# =>   <tr>
# =>     <th>s2</th>
# =>     <td>2</td>
# =>     <td>0</td>
# =>     <td>8</td>
# =>   </tr>
# =>   <tr>
# =>     <th>s3</th>
# =>     <td>3</td>
# =>     <td>6</td>
# =>     <td>0</td>
# =>   </tr>
# => </table>

Default to segment table

dashboard = Deep::Hash::Struct::Dashboard.new
dashboard.add_table(default: 0) do |t|
  t.add_header do |h|
    h.a = "h1"
    h.b = "h2"
    h.c = "h3"
  end

  t.add_body do |row|
    row.b = 2
    row.c = 3
  end

  t.add_body do |row|
    row.a = 4
    row.c = 6
  end

  t.add_body do |row|
    row.a = 7
    row.b = 8
  end
end

dashboard.tables # => [#<Table matrix=false>]

table = "<table>\n"
dashboard.tables[0].each do |rows|
  table << "  <tr>\n"
  rows.each do |row|
    if row.header?
      table << "    <th>#{row.name}</th>\n"
    else
      table << "    <td>#{row.value}</td>\n"
    end
  end
  table << "  </tr>\n"
end
table << "</table>\n"

puts table
# => <table>
# =>   <tr>
# =>     <th>h1</th>
# =>     <th>h2</th>
# =>     <th>h3</th>
# =>   </tr>
# =>   <tr>
# =>     <td>0</td>
# =>     <td>2</td>
# =>     <td>3</td>
# =>   </tr>
# =>   <tr>
# =>     <td>4</td>
# =>     <td>0</td>
# =>     <td>6</td>
# =>   </tr>
# =>   <tr>
# =>     <td>7</td>
# =>     <td>8</td>
# =>     <td>0</td>
# =>   </tr>
# => </table>

Create like html matrix table

dashboard = Deep::Hash::Struct::Dashboard.new
dashboard.add_table(matrix: true) do |t|
  t.tr do |tr|
    tr.th "header1"
    tr.th "header2"
    tr.th "header3"
  end

  t.tr side: true do |tr|
    tr.th "side1"
    tr.td 1
    tr.td 2
    tr.td 3
  end

  t.tr side: true do |tr|
    tr.th "side2"
    tr.td 4
    tr.td 5
    tr.td 6
  end

  t.tr side: true do |tr|
    tr.th "side3"
    tr.td 7
    tr.td 8
    tr.td 9
  end
end

result = "<table>\n"
dashboard.each do |t|
  t.each do |tr|
    result << "  <tr>\n"
    tr.each do |cell|
      if cell.side_or_header?
        result << "    <th>#{cell.name}</th>"
      else
        result << "    <td>#{cell.value}</td>"
      end
      result << "\n"
    end
    result << "  </tr>\n"
  end
end
result << "</table>\n"

puts table

# => <table>
# =>   <tr>
# =>     <th></th>
# =>     <th>header1</th>
# =>     <th>header2</th>
# =>     <th>header3</th>
# =>   </tr>
# =>   <tr>
# =>     <th>side1</th>
# =>     <td>1</td>
# =>     <td>2</td>
# =>     <td>3</td>
# =>   </tr>
# =>   <tr>
# =>     <th>side2</th>
# =>     <td>4</td>
# =>     <td>5</td>
# =>     <td>6</td>
# =>   </tr>
# =>   <tr>
# =>     <th>side3</th>
# =>     <td>7</td>
# =>     <td>8</td>
# =>     <td>9</td>
# =>   </tr>
# => </table>

Create like html segment table

dashboard = Deep::Hash::Struct::Dashboard.new
dashboard.add_table do |t|
  t.tr do |tr|
    tr.th "header1"
    tr.th "header2"
    tr.th "header3"
  end

  t.tr do |tr|
    tr.td 1
    tr.td 2
    tr.td 3
  end

  t.tr do |tr|
    tr.td 4
    tr.td 5
    tr.td 6
  end

  t.tr do |tr|
    tr.td 7
    tr.td 8
    tr.td 9
  end
end

result = "<table>\n"
dashboard.each do |t|
  t.each do |tr|
    result << "  <tr>\n"
    tr.each do |cell|
      if cell.side_or_header?
        result << "    <th>#{cell.name}</th>"
      else
        result << "    <td>#{cell.value}</td>"
      end
      result << "\n"
    end
    result << "  </tr>\n"
  end
end
result << "</table>\n"

puts table

# => <table>
# =>   <tr>
# =>     <th>header1</th>
# =>     <th>header2</th>
# =>     <th>header3</th>
# =>   </tr>
# =>   <tr>
# =>     <td>1</td>
# =>     <td>2</td>
# =>     <td>3</td>
# =>   </tr>
# =>   <tr>
# =>     <td>4</td>
# =>     <td>5</td>
# =>     <td>6</td>
# =>   </tr>
# =>   <tr>
# =>     <td>7</td>
# =>     <td>8</td>
# =>     <td>9</td>
# =>   </tr>
# => </table>

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/etiopiamokamame/deep-hash-struct. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

FAQs

Package last updated on 12 Feb 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc