[英]How can I use Ramda's omit() function on a deeply nested object member in javascript
我有一种情况,我想在展平和导出到 CSV 之前删除对象树的任何部分。 Ramda是我在 JS 中为FP选择的库,但我注意到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}}
我认为Lenses是一种更实用的方法。
R.over(R.lensProp('audience_sizes'), R.omit(['fb']), R.omit(['id'], obj));
DissocPath看起来像您要找的东西。 使用它或镜头进行更复杂的深度更新。
我通过使用以下功能解决了这个问题。 在下面的解决方案中,如何避免使用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;
});
谢谢!
根据更多经验丰富的omitDeep
用户的建议,我将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!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.