5
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

Ulysse BN
  • 10,116
  • 7
  • 54
  • 82
Joe
  • 4,274
  • 32
  • 95
  • 175

5 Answers5

13

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},
  {}
)
Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
3

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

2

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>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

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’ }

0

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.

prof
  • 721
  • 4
  • 6