hughsk / flat

:steam_locomotive: Flatten/unflatten nested Javascript objects
BSD 3-Clause "New" or "Revised" License
1.78k stars 196 forks source link

Add transformFirst option to allow modification of key to provide first key capability #107

Open jottinger opened 4 years ago

jottinger commented 4 years ago

I will be submitting a PR momentarily.

Example code for flatten, including CURRENT transformKey:

  test('Transformed Keys', function () {
    assert.deepStrictEqual(flatten({
      hello: {
        world: {
          again: 'good morning'
        }
      },
      lorem: {
        ipsum: {
          dolor: 'good evening'
        }
      }
    }, {
      transformKey: function (key) {
        return '__' + key + '__'
      }
    }), {
      '__hello__.__world__.__again__': 'good morning',
      '__lorem__.__ipsum__.__dolor__': 'good evening'
    })
  })

  test('Transformed First Key', function () {
    assert.deepStrictEqual(flatten({
      hello: {
        world: {
          again: 'good morning'
        }
      },
      lorem: {
        ipsum: {
          dolor: 'good evening'
        }
      }
    }, {
      transformFirst: function (key) {
        return '__' + key + '__'
      }
    }), {
      '__hello__.world.again': 'good morning',
      '__lorem__.ipsum.dolor': 'good evening'
    })
  })

  test('Transformed First Key with Custom Delimiter', function () {
    assert.deepStrictEqual(flatten({
      hello: {
        world: {
          again: 'good morning'
        }
      },
      lorem: {
        ipsum: {
          dolor: 'good evening'
        }
      }
    }, {
      transformFirst: function (key) {
        return '__' + key + '__'
      },
      delimiter: ':'
    }), {
      '__hello__:world:again': 'good morning',
      '__lorem__:ipsum:dolor': 'good evening'
    })
  })

  test('Transformed First Key to Add Prefix with Default Delimiter', function () {
    assert.deepStrictEqual(flatten({
      hello: {
        world: {
          again: 'good morning'
        }
      },
      lorem: {
        ipsum: {
          dolor: 'good evening'
        }
      }
    }, {
      transformFirst: function (key, delim) {
        return 'foo' + delim + key
      }
    }), {
      'foo.hello.world.again': 'good morning',
      'foo.lorem.ipsum.dolor': 'good evening'
    })
  })

  test('Transformed First Key to Add Prefix with Custom Delimiter', function () {
    assert.deepStrictEqual(flatten({
      hello: {
        world: {
          again: 'good morning'
        }
      },
      lorem: {
        ipsum: {
          dolor: 'good evening'
        }
      }
    }, {
      transformFirst: function (key, delim) {
        return 'foo' + delim + key
      },
      delimiter: ':'
    }), {
      'foo:hello:world:again': 'good morning',
      'foo:lorem:ipsum:dolor': 'good evening'
    })
  })

  test('Transformed Results and Keys', function () {
    assert.deepStrictEqual(flatten({
      hello: {
        world: {
          again: 'good morning'
        }
      },
      lorem: {
        ipsum: {
          dolor: 'good evening'
        }
      }
    }, {
      transformKey: function (key) {
        return '__' + key + '__'
      },
      transformFirst: function (key, delim) {
        return 'translated' + delim + key
      }
    }), {
      'translated.__hello__.__world__.__again__': 'good morning',
      'translated.__lorem__.__ipsum__.__dolor__': 'good evening'
    })
  })

Example code for unflatten:

    assert.deepStrictEqual(unflatten({
      'foo.hello.world.again': 'good morning',
      'foo.lorem.ipsum.dolor': 'good evening'
    }, {
      transformFirst: function (key, delim) {
        return key.substring(('foo'+delim).length)
      }
    }), {
      hello: {
        world: {
          again: 'good morning'
        }
      },
      lorem: {
        ipsum: {
          dolor: 'good evening'
        }
      }
    })
  })

  test('Transformed First Key and Subsequent Keys', function () {
    assert.deepStrictEqual(unflatten({
      'foo.__hello__.__world__.__again__': 'good morning',
      'foo.__lorem__.__ipsum__.__dolor__': 'good evening'
    }, {
      transformKey: function (key) {
        return key.substring(2, key.length - 2)
      },
      transformFirst: function (key, delim) {
        return key.substring(('foo'+delim).length)
      }
    }), {
      hello: {
        world: {
          again: 'good morning'
        }
      },
      lorem: {
        ipsum: {
          dolor: 'good evening'
        }
      }
    })
  })
vandres commented 2 years ago

I really could need this feature. Maybe a improvement could be, to extend transformKey, to provide the depth in the callback. Then we could just react to "depth === 0"