javascript - 通过任意数量的参数设置对象的嵌套键/值
问题描述
假设我有一些对象,例如:
const someObj = {
x: null,
y: {
z: null
},
a: {
b: {
c: null
}
}
}
我想创建一个函数来使用类似的东西设置值:
const setKV = (obj, ...keyArray) => {
/* Not quite sure how to phrase this function */
const val = keyArray.pop()
}
这样我就可以设置值:
x
和setKV(someObj, 'x', true)
z
和setKV(someObj, 'y', 'z', true)
c
和setKV(someObj, 'a', 'b', 'c', true)
我如何通过这个任意数量的参数定义对象的嵌套键?
解决方案
您可以使用...rest
下面的 rest 参数和 spread 参数轻松地做到这一点。setKV
不改变其输入对象,o
;总是返回一个新对象。
const setKV = (o = {}, key, value, ...rest) =>
rest.length === 0
? { ...o, [key]: value }
: { ...o, [key]: setKV (o[key], value, ...rest) }
console.log
( setKV ({ a: 0 }, 'b', 1)
// { a: 0, b: 1 }
, setKV ({ a: { b: { c: false } } }, 'a', 'b', 'c', true)
// { a: { b: { c: true } } }
, setKV ({}, 'a', 'b', 'c', 1)
// { a: { b: { c: 1 } } }
, setKV ({ a: { b: { c: 0 } } }, 'a', 'b', 'd', 0)
// { a: { b: { c: 0, d: 0 } } }
, setKV ({ a: { b: { c: 0 } } }, 'a', 'b', 1)
// { a: { b: 1 } }
, setKV ({ a: 1, b: { c: 2, d: { e: 3 } } }, 'b', 'd', 'e', { f: 4 })
// { a: 1, b: { c: 2, d: { e: { f: 4 } } } }
, setKV ({ a: 0 }, 'b')
// { a: 0, b: undefined }
)
“如果我确实想改变输入对象......”
虽然应该避免突变,但您的程序的特定需求可能需要使用它们。在这种情况下,检查mutKV
一下,看看它与上面的实现有何不同
const mutKV = (o = {}, key, value, ...rest) =>
rest.length === 0
? (o[key] = value, o)
: (o[key] = mutKV (o[key], value, ...rest), o)
const data =
{ a: 0 }
mutKV (data, 'b', 1)
console.log (data)
// { a: 0, b: 1 }
mutKV (data, 'c', 'd', 2)
console.log (data)
// { a: 0, b: 1, c: { d: 2 } }
mutKV (data, 'c', 'd', 3)
console.log (data)
// { a: 0, b: 1, c: { d: 0 } }
mutKV (data, 'c', 4)
console.log (data)
// { a: 0, b: 1, c: 4 }
这为本书打开了关于副作用的简短课程,并使用effect
. mut
下面我们使用创建一个效果effect
,然后mut
在每个分支中使用mutKV
。该程序的行为与mutKV
上述相同。
const effect = f => x =>
(f (x), x)
const mut = (key, value) =>
effect (o => o[key] = value)
const mutKV = (o = {}, key, value, ...rest) =>
rest.length === 0
? mut (key, value) (o)
: mut (key, mutKV (o[key], value, ...rest)) (o)
推荐阅读
- browser - 隐藏式字幕轨道不适用于所有浏览器
- selenium - 自定义 /etc/hosts 文件上的 docker-selenium ?
- python - 这里继承合适吗?
- javascript - 将点击事件绑定到 Javascript 函数
- android - 尽管不在布局中,但仍在创建片段
- vba - 如何找出使用 VBA 写入 Excel 单元格时出现错误的原因?
- docker - CSV 数据集配置 - Jmeter Docker
- amazon-web-services - AWS Fargate ALB DNS 未解析
- android-studio - Android Studio 3.3 缺少喷气背包创建选项
- c - For循环在C中随机停止