Как я могу использовать функцию Ramit omit () для глубоко вложенного объекта-члена в JavaScript - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть ситуация, когда я хочу удалить любую часть дерева объектов перед выравниванием и экспортом в CSV. Ramda - моя библиотека выбора для FP в JS, но я заметил, что функция R.omit() работает только на одном уровне глубины целевого объекта.Как я могу сделать так, чтобы я мог сделать следующее?

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

Я ожидал бы следующий результат:

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

Ответы [ 4 ]

0 голосов
/ 29 сентября 2018

Основываясь на советах более опытных пользователей Ramda, я изменил свою функцию omitDeep следующим образом:

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

Спасибо @Buggy и @Ebuall!

0 голосов
/ 29 сентября 2018

Я думаю Линзы - более функциональный способ сделать это.

R.over(R.lensProp('audience_sizes'), R.omit(['fb']), R.omit(['id'], obj));
0 голосов
/ 29 сентября 2018

DissocPath выглядит так, как вы ищете.Используйте его или линзы для более сложных глубоких обновлений.

0 голосов
/ 29 сентября 2018

Я решил эту проблему с помощью следующей функции.Как я могу избежать использования eval () при обработке глубокой ссылки на члены объекта в приведенном ниже решении?По сути, я ищу лучший способ реализации этой функции:

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

Спасибо!

...