最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Rename keys with ramda js - Stack Overflow

programmeradmin3浏览0评论
const orignalArr = [
  {
    personName: 'Joe'
  }
]

expected output:

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

I'm thinking the renamed keys are defined in an object (but fine if there's a better way to map them):

const keymaps = {
  personName: 'name'
};

How can I do this with Ramda?

Something with R.map

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

expected output:

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

I'm thinking the renamed keys are defined in an object (but fine if there's a better way to map them):

const keymaps = {
  personName: 'name'
};

How can I do this with Ramda?

Something with R.map

Share Improve this question edited May 20, 2019 at 12:15 Ulysse BN 11.4k7 gold badges61 silver badges93 bronze badges asked May 20, 2019 at 11:40 JoeJoe 4,23432 gold badges106 silver badges180 bronze badges
Add a comment  | 

5 Answers 5

Reset to default 14

There is an entry in Ramda's Cookbook for this:

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>

But with the ubiquity of ES6, it's pretty easy to write this directly:

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

You can combine Ramda with Ramda Adjunct. Using the renameKeys (https://char0n.github.io/ramda-adjunct/2.27.0/RA.html#.renameKeys) method is very useful. With it you can simply do something like this:

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

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

const __people__ = renameKeys(people);

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

Hope it helped you :)

This is my take on renameKeys. The main idea is to separate the keys and values to two array. Map the array of keys, and replace with values from keyMap (if exist), then zip back to object:

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>

My idea to make it is to first check that the old prop I want to rename exists, and the new key I want to create doesn’t.

Then, I will use the S_ common combinator to make it point-free.

Find JS common combinators 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’ }

Here is my own solution, not too many arrow functions (just one), mostly pure Ramda calls. And it is one of shortest, if not the shortest ;)

First, based on your example

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));

Second option, using any arbitrary lambda with renaming rules:

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 }));

Yields

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

Third, you can use object-based rename rules from the first example and use fallback strategy, e.g. replace like in the second example, instead of identity.

发布评论

评论列表(0)

  1. 暂无评论