基于提供的键遍历对象层次结构?
Traversing object hierarchy based on provided keys?
我有一个接受以下参数的函数:
set(section, field, pair, component, element, value)
部分,字段, pair 和 component 只是对象中的键。它们是路标,因此我们可以沿着层次结构向下移动。显然section是头部,我们的切入点
元素是目标键,值 是将要设置的值。
因为有不同深度的元素,我想做以下事情:
set('utility', null, null, null, 'exportId', 'banana')
这是浅层访问,在内部它会这样做:
dataObj[section][element] = value;
**/ As in
* data: {
utility: {
exportId: 'banana'
}
* }
*/
在其他情况下,当元素在Object内部较深时,可能需要做如下操作:
dataObj[section][field][pair][component][element] = value;
动态定义元素路径的最佳方法是什么,因此我们跳过作为 'null' 传入的键?
例如:
set('history', 'current', null, null, 'fruit', 'apple')
**/ As in
* data: {
history: {
current: {
fruit: 'apple'
}
}
* }
*/
将在内部构造为:
dataObj[section][field][element] = value;
正如您可能已经注意到的,我们跳过了 [pair][component]
,因为这些槽是作为 null
(s) 传入的。
无需使用一长串特定参数,只需将对象传递给函数即可。这样你只传递你需要的东西,并且不会有任何 "null" 引用来处理调用。
使用这个实现,这个调用可以缩短成这样:
您当前的实施:
set('utility', 'current', null, null, 'exportId', 'banana')
使用对象作为参数:
set({
section:'utility',
field:'current',
element: 'exportId',
value:'banana'
});
你可以使用 rest parameters to get the arguments passed to an array. Then create an object using reduceRight
function set(...paths) {
return paths.reduceRight((r, key, i) => key !== null ? { [key] : r } : r)
}
console.log(set('history', 'current', null, null, 'fruit', 'apple'))
console.log(set('utility', null, null, null, 'exportId', 'banana'))
上述函数将构造一个基于路径的嵌套对象。如果你只想更新一个现有的对象,你可以遍历对象并像这样设置值:
function set(dataObj, ...paths) {
let value = paths.pop(),
nested = dataObj;
for (let i = 0; i < paths.length; i++) {
const path = paths[i];
if (i === paths.length - 1 && nested)
nested[path] = value; // set the value if it's the final item
if (path !== null && nested)
nested = nested[path]; // get another level of nesting
}
return dataObj;
}
let obj = { utility: { exportId: 'banana' } }
console.log(set(obj, 'utility', null, null, null, 'exportId', 'orange'))
obj = {
history: {
current: {
fruit: 'apple'
}
}
}
console.log(set(obj, 'history', 'current', null, null, 'fruit', 'orange'))
我有一个接受以下参数的函数:
set(section, field, pair, component, element, value)
部分,字段, pair 和 component 只是对象中的键。它们是路标,因此我们可以沿着层次结构向下移动。显然section是头部,我们的切入点
元素是目标键,值 是将要设置的值。
因为有不同深度的元素,我想做以下事情:
set('utility', null, null, null, 'exportId', 'banana')
这是浅层访问,在内部它会这样做:
dataObj[section][element] = value;
**/ As in
* data: {
utility: {
exportId: 'banana'
}
* }
*/
在其他情况下,当元素在Object内部较深时,可能需要做如下操作:
dataObj[section][field][pair][component][element] = value;
动态定义元素路径的最佳方法是什么,因此我们跳过作为 'null' 传入的键?
例如:
set('history', 'current', null, null, 'fruit', 'apple')
**/ As in
* data: {
history: {
current: {
fruit: 'apple'
}
}
* }
*/
将在内部构造为:
dataObj[section][field][element] = value;
正如您可能已经注意到的,我们跳过了 [pair][component]
,因为这些槽是作为 null
(s) 传入的。
无需使用一长串特定参数,只需将对象传递给函数即可。这样你只传递你需要的东西,并且不会有任何 "null" 引用来处理调用。
使用这个实现,这个调用可以缩短成这样:
您当前的实施:
set('utility', 'current', null, null, 'exportId', 'banana')
使用对象作为参数:
set({
section:'utility',
field:'current',
element: 'exportId',
value:'banana'
});
你可以使用 rest parameters to get the arguments passed to an array. Then create an object using reduceRight
function set(...paths) {
return paths.reduceRight((r, key, i) => key !== null ? { [key] : r } : r)
}
console.log(set('history', 'current', null, null, 'fruit', 'apple'))
console.log(set('utility', null, null, null, 'exportId', 'banana'))
上述函数将构造一个基于路径的嵌套对象。如果你只想更新一个现有的对象,你可以遍历对象并像这样设置值:
function set(dataObj, ...paths) {
let value = paths.pop(),
nested = dataObj;
for (let i = 0; i < paths.length; i++) {
const path = paths[i];
if (i === paths.length - 1 && nested)
nested[path] = value; // set the value if it's the final item
if (path !== null && nested)
nested = nested[path]; // get another level of nesting
}
return dataObj;
}
let obj = { utility: { exportId: 'banana' } }
console.log(set(obj, 'utility', null, null, null, 'exportId', 'orange'))
obj = {
history: {
current: {
fruit: 'apple'
}
}
}
console.log(set(obj, 'history', 'current', null, null, 'fruit', 'orange'))