gpt4 book ai didi

javascript - 更新的嵌套属性没有多个循环

转载 作者:行者123 更新时间:2023-11-29 23:28:54 24 4
gpt4 key购买 nike

我面临的一个问题是,在 JavaScript 中操作数组或对象时,我总是重复自己的话。我们正在远离 jQuery 时代,在该时代我们可以简单地从 DOM 获取和修改统计数据。

以这个嵌套的对象数组为例

[
{
"data": [
{
"name": "item1",
"checked": false
},
{
"name": "item2",
"checked": false
}
]
}
]

为了更改 item2checked 属性,我必须执行 2 个循环

const newData = data.map(o=>{
return {
...o,
data: o.data.map(o2=>{
if(o2.name === 'item2'){
return{
...o2,
'checked': true
}
}
return o2
})
}
})

这个问题还有更好的选择吗?

最佳答案

一种方法是认识到复杂数据结构中的每一层嵌套都是一个“仿函数”(超出了这个答案的解释范围,但网上有很多很好的解释)。

functors-101 的解释是,它是“可映射性”概念的概括,因此您可以映射数组、对象、可观察对象以及各种古怪的事物,同时保留它们的结构。

无论如何,鉴于您的数据结构是一个嵌入在仿函数中的仿函数,您可以通过简单地将 map 函数与其自身组合尽可能多的次数来映射到最深层次嵌套仿函数结构中的级别。

例如在你的情况下你可以使用 map3 来做:

const result = map3(x => x.name === "item2" ? { ...x, checked: true } : x)(data)

这是一个完整的 JS 实现(我内联实现了 FP 库位,而不是使用依赖项来阐明正在发生的事情):

// FP utils (you can use a library like Sanctuary or Ramda to get these)
const merge = (o1, o2) => ({
...o1,
...o2
})
const compose = fns => fns.reduce((f, g) => (...args) => f(g(...args)))

const mapArr = f => a => a.map(f)
const mapObj = f => o =>
Object.keys(o)
.map(k => ({
[k]: f(o[k])
}))
.reduce(merge)
const mapImpls = new Map([[Object, mapObj], [Array, mapArr]])

const map = f => x => mapImpls.get(x.constructor)(f)(x)

const map2 = compose([map, map])
const map3 = compose([map, map, map])
const map4 = compose([map, map, map, map])
// ...

// Your code
const data = [
{
data: [
{
name: "item1",
checked: false
},
{
name: "item2",
checked: false
}
]
}
]
const projection = x =>
x.name === "item2"
? {
...x,
checked: true
}
: x
const result = map3(projection)(data)
console.log(result)

据我所知,第一个给这个模式起名字的人是Conal Elliott ,在他关于“语义编辑器组合器”的博客文章中。

关于javascript - 更新的嵌套属性没有多个循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48001199/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com