javascript - How can I deeply map over object with Ramda
问题描述
I'm trying to find all "template values" e.g. { template: 'Date: <now>'}
using a map function to get this basic behaviour:
deepMap(mapFn, {a: 1, b: { c: 2, d: { template: 'Date: <now>'}}})
>> {a: 1, b: { c: 2, d: 'Date: 13423234232'}}
This is what I have so far. The interpolation of the template object does happen, but it does not replace the value.
const obj = {a: 1, b: { c: 2, d: { template: 'Date: <now>'}}};
const deepMap = (fn, xs) =>
mapObjIndexed(
(val, key, obj) =>
or(is(Array, val), is(Object, val))
? deepMap(fn, fn(val))
: fn(val),
xs
);
const checkFn = ({ template }) => template;
const transformFn = (val, key) => {
const interpolated = val.template.replace('<now>', Date.now())
console.log(interpolated);
return interpolated;
};
const mapFn = n =>
checkFn(n)
? transformFn(n)
: n;
console.clear();
deepMap(mapFn, obj);
>> {"a": 1, "b": {"c": 2, "d": {}}}
解决方案
问题是您deepMap
再次调用映射值 - 但映射值不再是对象,而是字符串。
or(is(Array, val), is(Object, val))
? deepMap(fn, fn(val))
: fn(val),
如果 val is { template: 'Date: <now>'}
,则 val 是一个对象,可以进行深度映射,但fn(val)
它是一个 String ( "Date: 123123123"
),应该简单地返回。一种解决方案是is
检查映射值,而不是原始值:
(val, key) => {
const mappedVal = fn(val);
return or(is(Array, mappedVal), is(Object, mappedVal))
? deepMap(fn, mappedVal)
: mappedVal;
},
另一种可能性是检查 map 函数是否返回了不同于原始值的值,并且在这种情况下不递归。
推荐阅读
- javascript - React 中两个孪生兄弟组件之间的通信
- javascript - 在 React 中状态更改时重新渲染组件
- javascript - 用数组中的值替换字符串中的特定字符
- actionscript-3 - 为什么 scaleY=-1 不反映 AS3 代码中的文本?
- wiremock - Wiremock - 通过转发代理录制/播放
- google-cloud-platform - Google Cloud SQL On Demand 激活
- python - 在 warnings.simple_filter() 过滤器中指定消息基于类别而不是消息
- css - Sphinx:如何设置访问链接的颜色(sphinx_rtd_theme)
- sql-server - 如何将用户定义的数据类型参数传递给 SSRS 报表查询?
- javascript - 你如何为 reactjs 中的元素分配新的属性