Infinitely nested hashes in Javascript (Coffeescript)

The NestedHash class allows you to read and write hashes of any depth. Examples:

hash = {}
NestedHash.write hash, 'a', 'b', 'c', 'value' # => { a: { b: { c: 'value' } } }
NestedHash.read hash, 'a', 'b', 'c' # => 'value'
NestedHash.read hash, 'a' # => { b: { c: 'value' } }
NestedHash.read hash, 'foo', 'bar' # => undefined

Inspired by victusfate Show archive.org snapshot .

Code

class @NestedHash

  @read: (objekt, keys...) ->
    if objekt and keys.length
      @read objekt[keys[0]], keys[1...]...
    else
      objekt

  @write: (objekt, keys..., value) ->
    objekt ?= {}

    if keys.length
      key = keys[0]
      objekt[key] = @write(objekt[key], keys[1...]..., value)
      objekt
    else
      objekt = value

Jasmine-Spec

describe 'NestedHash', ->

  describe '.write()', ->
    it 'writes nested values to a hash', ->
      hash = {}
      NestedHash.write hash, 'level1', 'level2', 'value'

      expect(hash).toEqual
        level1:
          level2: 'value'

    it 'overwrites existing values', ->
      hash =
        level1:
          level2: 'value'

      NestedHash.write hash, 'level1', 'level2', 'new value'
      expect(hash).toEqual
        level1:
          level2: 'new value'

  describe '.read()', ->
    it 'reads nested values from a hash', ->
      hash =
        level1:
          level2: 'value'

      value = NestedHash.read hash, 'level1', 'level2'
      expect(value).toEqual 'value'

    it 'reads nested trees from a hash', ->
      hash =
        level1:
          level2: 'value'

      value = NestedHash.read hash, 'level1'
      expect(value).toEqual level2: 'value'

    it 'returns undefined when any of the keys is missing', ->
      value = NestedHash.read {}, 'foo', 'bar'
      expect(value).not.toBeDefined()
Dominik Schöler About 8 years ago