简体   繁体   中英

How can I use Ramda's omit() function on a deeply nested object member in javascript

I have a situation where I want to remove any part of an object tree before flattening and exporting to CSV. Ramda is my choice library for FP in JS, but I noticed the R.omit() function works at only one level deep of the target object. How can I make it such that I can do the following?

const R = require('ramda');

const obj = {
    id: 1,
    name: 'me',
    audience_sizes: {
        fb: 500,
        dfp: 2000,
        apn: 1800
    }
};

console.log(JSON.stringify(R.omit(['id', 'audience_sizes.fb'], obj)));

I would expect the following result:

{"name":"me","audience_sizes":{"dfp":2000, "apn": 1800}}

我认为Lenses是一种更实用的方法。

R.over(R.lensProp('audience_sizes'), R.omit(['fb']), R.omit(['id'], obj));

DissocPath look like what you are looking for. Use it or lenses for more complex deep updates.

I solved this problem by using the following function. How can I avoid the Use of eval() in handling deep reference of object members in the solution below? Basically, I'm looking for a better way of implementing this function:

//This is a supplemental function to Ramda's omit(), which allows deep key referencing
export const omitDeep = R.curry((keys, obj) => {
  if(!keys || keys.length===0) return obj;
  let newObj = Object.assign({}, obj);
  keys.forEach( key => {
      let keyParts = key.split('.');
      if(keyParts.length < 2) {
          newObj = R.omit(keyParts, newObj);
          return;
      }
      let target = newObj[keyParts[0]];
      let objString = `newObj.${keyParts[0]}`;
      for(let i=1; i < keyParts.length - 1; i++){
          target = target[keyParts[i]];
          objString += `.${keyParts[0]}`;
      }
      const subj = keyParts[keyParts.length-1];
      target = R.omit([subj], target);
      eval(`${objString} = target`);
   });
   return newObj;
});

Thanks!

Based on advice by more experienced Ramda users, I've refactored my omitDeep function to read as follows:

//This is a supplemental function to Ramda's omit(), which allows deep key referencing
export const omitDeep = R.curry((keys, obj) => {
  if(!keys || keys.length===0) return obj;
  let newObj = R.clone(obj);
  keys.forEach( key => {
      let keyParts = key.split('.');
      newObj = R.dissocPath(keyParts, newObj);
  });    
  return newObj;
});

Thanks @Buggy and @Ebuall!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM