使用ramdajs重命名对象的属性

时间:2016-12-19 18:52:02

标签: javascript ramda.js

我需要使用 ramdajs 重写一个对象的所有属性,该对象可能包含带连字符的单词到camelCase。

示例,属性名称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));
});

2 个答案:

答案 0 :(得分:3)

我不清楚你的尝试。使用该功能和一小部分基础设施将其应用于正确的对象,它似乎对我有用:

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功能,但您可以在整个网络上找到它们,或者很容易创建自己的功能。一个版本:

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

中使用

答案 1 :(得分:0)

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

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

相关问题