【发布时间】:2022-02-09 04:25:23
【问题描述】:
我正在尝试利用technique shown here 将对象中的值替换为ramda.js。与链接引用不同,我的对象有更多的嵌套层,因此它失败了。
在以下示例中,我们有一个对象详细说明了城市中的景点。首先它指定了城市,我们进入nyc,然后进入zoos,然后是StatenIslandZoo,最后我们到达zooInfo,它保存着两只动物的两条记录。在每一个中,我们在与 animal 键关联的值中都有 aniaml 的名称。我想通过用另一个字符串替换它来更正值的字符串并返回整个 cityAttractions 对象的新副本。
const cityAttractions = {
"cities": {
"nyc": {
"towers": ["One World Trade Center", "Central Park Tower", "Empire State Building"],
"zoos": {
"CentralParkZoo": {},
"BronxZoo": {},
"StatenIslandZoo": {
"zooInfo": [
{
"animal": "zebra_typo", // <- replace with "zebra"
"weight": 100
},
{
"animal": "wrongstring_lion", // <- replace with "lion"
"weight": 1005
}
]
}
}
},
"sf": {},
"dc": {}
}
}
所以我定义了一个和this one很相似的函数:
const R = require("ramda")
const myAlter = (myPath, whereValueEquals, replaceWith, obj) => R.map(
R.when(R.pathEq(myPath, whereValueEquals), R.assocPath(myPath, replaceWith)),
obj
)
然后调用myAlter()并将输出存储到altered:
const altered = myAlter(["cities", "nyc", "zoos", "StatenIslandZoo", "zooInfo", "animal"], "zebra_typo", "zebra", cityAttractions)
但是在检查时,我意识到没有发生任何替换:
console.log(altered.cities.nyc.zoos.StatenIslandZoo.zooInfo)
// [
// { animal: 'zebra_typo', weight: 100 },
// { animal: 'wrongstring_lion', weight: 1005 }
// ]
一些疑难解答
如果我们返回并检查原始的cityAttractions 对象,那么我们可以首先仅提取cityAttractions.cities.nyc.zoos.StatenIslandZoo.zooInfo 的级别,然后使用myAlter() 对其进行操作。
const ZooinfoExtraction = R.path(["cities", "nyc", "zoos", "StatenIslandZoo", "zooInfo"])(cityAttractions)
console.log(ZooinfoExtraction)
// [
// { animal: 'zebra_typo', weight: 100 },
// { animal: 'wrongstring_lion', weight: 1005 }
// ]
console.log(myAlter(["animal"], "zebra_typo", "zebra", ZooinfoExtraction))
// here it works!
// [
// { animal: 'zebra', weight: 100 },
// { animal: 'wrongstring_lion', weight: 1005 }
// ]
因此,出于某种原因,myAlter() 适用于提取的 ZooinfoExtraction,但不适用于原始 cityAttractions。这是一个问题,因为我需要整个原始结构(只需替换指定的值)。
编辑 - 疑难解答 2
我想问题在于
R.path(["cities", "nyc", "zoos", "StatenIslandZoo", "zooInfo", "animal"], cityAttractions)
返回undefined。
【问题讨论】:
标签: javascript ramda.js