使用 ramdajs 重命名对象的属性

Using ramdajs for renaming properties of an object

我需要使用 ramdajs.

重写一个对象的所有属性,该对象可能包含带连字符的单词以驼峰式命名

例如,属性 名称 animation-timing-function 应该变成 animationTimingFunction 依此类推。

能否请您举个例子:

这是我应该转换的数据:

var data = {
  "bounce": [
    {
      "animation-timing-function": "cubic-bezier(0.215, 0.610, 0.355, 1.000)",
      "transform": "translate3d(0,0,0)",
      "offset": 0
    },
    {
      "animation-timing-function": "cubic-bezier(0.215, 0.610, 0.355, 1.000)",
      "transform": "translate3d(0,0,0)",
      "offset": 0.2
    },
    {
      "animation-timing-function": "cubic-bezier(0.755, 0.050, 0.855, 0.060)",
      "transform": "translate3d(0, -30px, 0)",
      "offset": 0.4
    },
    {
      "animation-timing-function": "cubic-bezier(0.755, 0.050, 0.855, 0.060)",
      "transform": "translate3d(0, -30px, 0)",
      "offset": 0.43
    },
    {
      "animation-timing-function": "cubic-bezier(0.215, 0.610, 0.355, 1.000)",
      "transform": "translate3d(0,0,0)",
      "offset": 0.53
    },
    {
      "animation-timing-function": "cubic-bezier(0.755, 0.050, 0.855, 0.060)",
      "transform": "translate3d(0, -15px, 0)",
      "offset": 0.7
    },
    {
      "animation-timing-function": "cubic-bezier(0.215, 0.610, 0.355, 1.000)",
      "transform": "translate3d(0,0,0)",
      "offset": 0.8
    },
    {
      "transform": "translate3d(0,-4px,0)",
      "offset": 0.9
    },
    {
      "animation-timing-function": "cubic-bezier(0.215, 0.610, 0.355, 1.000)",
      "transform": "translate3d(0,0,0)",
      "offset": 1
    }
  ]
};

我尝试修改此收据但没有成功:

const renameKeys = R.curry((keysMap, obj) => {
  return R.reduce((acc, key) => {
    acc[keysMap[key] || key] = obj[key];
    return acc;
  }, {}, R.keys(obj));
});

我不清楚你尝试了什么。有了这个功能和一点点基础设施来将它应用于正确的对象,它似乎对我有用:

R.over(lensProp('bounce'), map(renameKeys({
  'animation-timing-function': 'animationTimingFunction'
})), data)

//=> {bounce: [
//   {
//     animationTimingFunction: "cubic-bezier(0.215, 0.610, 0.355, 1.000)",
//     offset: 0,
//     transform: "translate3d(0,0,0)"
//   },
//   {
//     animationTimingFunction: "cubic-bezier(0.215, 0.610, 0.355, 1.000)",
//     offset: 0.2,
//     transform: "translate3d(0,0,0)"
//   },
//   // ...
// ]}

但这似乎是名称中唯一带有连字符的键,所以也许我只是感到困惑。应该还有其他人吗?

您可以在 Ramda REPL.

上看到实际效果

更新

根据后续评论,看起来 Ramda's Cookbook right before 中的条目更合适:

const mapKeys = R.curry((fn, obj) =>
  R.fromPairs(R.map(R.adjust(fn, 0), R.toPairs(obj)))
);

尽管 Ramda 不包含 camelCase 函数,但您可以在整个 Web 上找到它们,或者很容易地创建自己的函数。一个版本:

const camelCase = (str) => str.replace(/[-_]([a-z])/g, 
  (m) => m[1].toUpperCase()
)

有了这些,就更简单了:

R.over(lensProp('bounce'), map(mapKeys(camelCase)), data)

//=> {bounce: [
//   {
//     animationTimingFunction: "cubic-bezier(0.215, 0.610, 0.355, 1.000)",
//     anotherHyphenatedEntry: "foo",
//     offset: 0,
//     transform: "translate3d(0,0,0)"
//   },
//   {
//     animationTimingFunction: "cubic-bezier(0.215, 0.610, 0.355, 1.000)",
//     offset: 0.2,
//     transform: "translate3d(0,0,0)"
//   },
//   // ...

同样,此版本也可用于 Ramda REPL

此变体也重命名所有嵌套键

const isObject = o => equals(type(o), 'Object')
const rKeys = fn => ifElse(isObject, renameKeys(fn), identity)
const mapper = fn => map(([key, value]) => [fn(key), rKeys(fn)(value)])
let renameKeys = curry((fn, obj) => compose(
  fromPairs,
  mapper(fn),
  toPairs
)(obj))

来自

{gender: {userinfo: 2, purchase: ['one', 'two'], key: {nestedKey: 1}}, anotherKey: {anotherAnotherKey: 3}}

{ANOTHERKEY: {ANOTHERANOTHERKEY: 3}, GENDER: {KEY: {NESTEDKEY: 1}, PURCHASE: ["one", "two"], USERINFO: 2}}

Playground