用Ramda JS重命名键

时间:2019-05-20 11:40:48

标签: javascript ramda.js

const orignalArr = [
  {
    personName: 'Joe'
  }
]

预期输出:

const convertedArr = [
  {
    name: 'Joe'
  }
]

我在想重命名的键是在对象中定义的(但是如果有更好的映射方法,那很好):

const keymaps = {
  personName: 'name'
};

我如何用Ramda做到这一点?

R.map

5 个答案:

答案 0 :(得分:3)

您可以将Ramda与Ramda Adjunct结合使用。使用renameKeyshttps://char0n.github.io/ramda-adjunct/2.27.0/RA.html#.renameKeys)方法非常有用。有了它,您可以简单地执行以下操作:

const people = [
  {
    personName: 'Joe'
  }
]

const renameKeys = R.map(RA.renameKeys({ personName: 'name' }));

const __people__ = renameKeys(people);

console.log(__people__) // [ { name: 'Joe' }]

希望它对您有所帮助:)

答案 1 :(得分:1)

为此an entry中有Ramda's Cookbook

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

const originalArr = [{personName: 'Joe'}]

console .log (
  R.map (renameKeys ({personName: 'name'}), originalArr)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

但是由于ES6无处不在,直接编写此代码很容易:

const renameKeys = (keysMap) => (obj) => Object.entries(obj).reduce(
  (a, [k, v]) => k in keysMap ? {...a, [keysMap[k]]: v} : {...a, [k]: v},
  {}
)

答案 2 :(得分:1)

这是我对renameKeys的看法。主要思想是将键和值分隔为两个数组。映射键的数组,并替换为keyMap中的值(如果存在),然后压缩回对象:

const { pipe, toPairs, transpose, converge, zipObj, head, map, last } = R

const renameKeys = keysMap => pipe(
  toPairs, // convert to entries
  transpose, // convert to array of keys, and array of values
  converge(zipObj, [ // zip back to object
    pipe(head, map(key => keysMap[key] || key)), // rename the keys
    last // get the values
  ])
)
  


const originalArr = [{ personName: 'Joe', lastName: 'greg' }]

const result = R.map(renameKeys({ personName: 'name' }), originalArr)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

答案 3 :(得分:0)

这里是我自己的解决方案,箭头函数不是太多(只有一个),主要是纯 Ramda 调用。它是最短的之一,如果不是最短的 ;)

首先,基于你的例子

const { apply, compose, either, flip, identity, map, mergeAll, objOf, prop, replace, toPairs, useWith } = require('ramda');             

const RenameKeys = f => compose(mergeAll, map(apply(useWith(objOf, [f]))), toPairs);

const originalArr = [
    {
        personName: 'Joe',
    },
];

const keymaps = {
    personName: 'name',
};

// const HowToRename = flip(prop)(keymaps); // if you don't have keys not specified in keymaps explicitly
const HowToRename = either(flip(prop)(keymaps), identity);

console.log(map(RenameKeys(HowToRename))(originalArr));

第二个选项,使用具有重命名规则的任意 lambda:

const { apply, compose, map, mergeAll, objOf, replace, toPairs, useWith } = require('ramda');

const RenameKeys = f => compose(mergeAll, map(apply(useWith(objOf, [f]))), toPairs);

const HowToRename = replace(/(?<=.)(?!$)/g, '_'); // for example

console.log(RenameKeys(HowToRename)({ one: 1, two: 2, three: 3 }));

收益

<块引用>

{ o_n_e: 1, t_w_o: 2, t_h_r_e_e: 3 }

第三,您可以使用第一个示例中基于对象的重命名规则并使用回退策略,例如replace 就像在第二个例子中一样,而不是 identity

答案 4 :(得分:-1)

我的想法是首先检查我要重命名的旧 prop 是否存在,而我要创建的新 key 不存在。

然后,我将使用 S_ 公共组合符使其无点。

查找 JS 常用组合符 here


const { 
    allPass, assoc, compose: B, complement, has, omit, prop, when
} = require('ramda');

const S_ = (f) => (g) => (x) => f (g (x)) (x);

const renameKey = (newKey) => (oldKey) => when(allPass([
    has(oldKey)
    , complement(has)(newKey)
]))
(B(omit([oldKey]), S_(assoc(newKey))(prop(oldKey))))
    
const obj = { fullname: 'Jon' };

renameKey('name')('fullname')(obj) // => { name: ‘Jon’ }