javascript - 在地图对象中设置和删除时确保原始文件的不变性
问题描述
我一直在研究如何在 JavaScript 中完成不变性/函数式编程,但我在使用以下代码时遇到了困难。从generateExample
函数返回的对象包含通过迭代对象数组来从映射中添加和删除键/值的方法。
场景 1 简单地使用 map 方法set
和delete
方法,并对 map 进行变异。setting
场景 2 在和deleting
键/值之前创建一个新映射。
set
我可以在每个循环中为每个 new 克隆地图foreach
,但我想这在计算上会太昂贵。
我还可以使用 Immutable.js (Map) 并为每个set
和返回一个新的数据结构delete
。我真的不想这样做。
从这个例子中返回的对象generateExample
将是唯一可以set
和delete
映射到地图的对象,所以也许担心这个例子中的不变性并不重要?
我想了解的是在设置和删除键/值时保持原始地图不变性的最佳方法是什么,甚至是否相关?
const sampleList = [
{
id: 'dog',
value: 'Dog',
},
{
id: 'cat',
value: 'Cat',
},
]
场景 1
const example = function generateExample() {
const container = new Map()
return {
add(list) {
list
.forEach((x) => {
container.set(x.id, x)
})
},
remove(list) {
list
.forEach((x) => {
container.delete(x.id)
})
},
read(id) {
return container.get(id)
},
}
}
情景 2
const example = function generateExample() {
let container = new Map()
return {
add(list) {
container = new Map(container)
list
.forEach((x) => {
container.set(x.id, x)
})
},
remove(list) {
container = new Map(container)
list
.forEach((x) => {
container.delete(x.id)
})
},
read(id) {
return container.get(id)
},
}
}
const test = example()
test.add(sampleList)
console.log(test.read('dog'))
解决方案
在这两种情况下,您都有突变。在第一种情况下,突变在Map
对象上,在第二种情况下,突变在容器值本身上,然后在Map
对象上。我建议不要有这一层,而只是按Map
原样处理对象,但如果情况必须如此像这样,我宁愿做这样的事情
const example = function generateExample(defaultList) {
let container = new Map(defaultList)
return {
add(list) {
container = new Map(container.concat(list));
},
remove(list) {
container = new Map(container.filter(item => !list.includes(item)))
},
read(id) {
return container.get(id)
},
}
}
推荐阅读
- java - QueryDsl 不会为 git 子模块的 @Entity 类生成 q-classes
- mysql - 如何从两个不同的表中获取两个不同列的总和并将它们分组
- java - Spring data couchbase 4.0.0 - 使用列表保存对象始终为空
- json - Azure Cosmos DB - 如何从类似于从 SQL 表中检索列名的文档中检索 json 属性
- pandas - 将字典中的所有值弹出到单独的变量中
- powershell - 我怎样才能让我的 curl 命令在 gitlab-ci 中工作?
- flutter - 如何在 Flutter 中的图标之间绘制垂直连接线?
- r - 无法使用 R 执行迭代
- python - how to sort the bar chart values in python?
- javascript - 从 cellrenderer 调用父函数,例如在 vuejs ag-grid-vue 上发出