动态获取嵌套对象key的所有路径
Dynamically get all the paths of the keys of a nested object
我正在尝试动态检索嵌套对象的键。我可以拥有的对象示例:
{
ts: "2021-05-06T11:06:18Z",
pr: 94665,
pm25: 5,
co2: 1605,
hm: 32,
m: {
isConnected: true,
wifidBm: 0,
},
pm1: 5,
s: {
"0": {
runningTime: 0,
sn: "05064906137109790000",
wearRate: 0,
enabled: true,
co2: 1605,
},
"1": {
enabled: false,
sn: "125630092251006",
},
"2": {
enabled: false,
sn: "05064906137109450000",
},
"3": {
fanStatus: 0,
pm25: 5,
pm1: "5",
e: {
rawSensorError: 0,
},
pm10: 5,
runningTime: 0,
sn: "125630100924141",
wearRate: 0,
enabled: true,
},
},
id: "avo_jggv6bsf211",
tp: "20.6",
pm10: 5,
type: "monitor",
}
例如,我需要:
str = 'ts, pr, pm25, co2, hm, "m.isConnected, m. wifiBm, pm1, s.0.runningTime, s.0.sn, ...'
这就是我现在的代码:
guessHeader(object: MeasurementModel | any, parentKey?: string): string[] {
// Looping on object's keys
Object.keys(object).forEach(key => {
if (typeof object[key] === 'object' && key !== 'ts') {
// If the object is an array recurse in it
return this.guessHeader(object[key], key)
} else {
// If we have a parentKey keep header as
if (parentKey)
this.header.push(`${parentKey}.${key}`)
else
this.header.push(key)
}
})
return this.header
}
它适用于密钥 m,我有 m.isConnected 和 m.wifiBm 但对于 s.0.runningTime 我只有 0.runningTime。此外,此对象可以更改并嵌套得更多。我需要找到一种适用于任何情况的方法。我试图将键保存在一个数组中,然后解析它们但失败了。
问题在这里:
// If the object is an array recurse in it
return this.guessHeader(object[key], key)
这应该是
this.header.push(...this.guessHeader(object[key], parentKey === undefined ? key : `${parentKey}.${key}`))
此外,typeof null === 'object'
,因此在将 object[key]
传递给 guessHeader
.[=28 之前,您还应该检查 object[key]
是否为非空(例如 typeof object[key] === 'object' && object[key]
) =]
还有一点就是MeasurementModel | any
和any
是一样的。避免使用类型安全的 any
和 。
guessHeader
的实现可能如下所示:
guessHeader(object: object, parentKey?: string): string[] {
Object.keys(object).forEach(key => {
const newKey = parentKey === undefined ? key : `${parentKey}.${key}`
const value = (object as Record<string, unknown>)[key]
if (typeof value === 'object' && value && key !== 'ts')
this.header.push(...this.guessHeader(value, newKey))
else
this.header.push(newKey)
})
return this.header
}
就我个人而言,我会使用 Object.entries
并执行如下操作:
const guessHeader = (object: object, acc = ''): string =>
Object.entries(object)
.map(([key, value]: [string, unknown]) =>
// It looks like you don't want to recurse into the ts key,
// which is why I used key !== 'ts'
// I'm guessing ts might be a Date; you could avoid recursing into
// all Dates by doing
// typeof value == 'object' && value && !(value instanceof Date)
key !== 'ts' && typeof value === 'object' && value
? guessHeader(value, `${acc}${key}.`)
: acc + key
)
.join(', ')
const input = {ts: '2021-05-06T11:06:18Z', pr: 94665, pm25: 5, co2: 1605, hm: 32, m: {isConnected: true, wifidBm: 0}, pm1: 5, s: {0: {runningTime: 0, sn: '05064906137109790000', wearRate: 0, enabled: true, co2: 1605}, 1: {enabled: false, sn: '125630092251006'}, 2: {enabled: false, sn: '05064906137109450000'}, 3: {fanStatus: 0, pm25: 5, pm1: '5', e: {rawSensorError: 0}, pm10: 5, runningTime: 0, sn: '125630100924141', wearRate: 0, enabled: true}}, id: 'avo_jggv6bsf211', tp: '20.6', pm10: 5, type: 'monitor'}
// same as above code block
const guessHeader = (object, acc = '') => Object.entries(object).map(([key, value]) => key !== 'ts' && typeof value === 'object' && value ? guessHeader(value, `${acc}${key}.`) : acc + key).join(', ')
console.log(guessHeader(input))
我正在尝试动态检索嵌套对象的键。我可以拥有的对象示例:
{
ts: "2021-05-06T11:06:18Z",
pr: 94665,
pm25: 5,
co2: 1605,
hm: 32,
m: {
isConnected: true,
wifidBm: 0,
},
pm1: 5,
s: {
"0": {
runningTime: 0,
sn: "05064906137109790000",
wearRate: 0,
enabled: true,
co2: 1605,
},
"1": {
enabled: false,
sn: "125630092251006",
},
"2": {
enabled: false,
sn: "05064906137109450000",
},
"3": {
fanStatus: 0,
pm25: 5,
pm1: "5",
e: {
rawSensorError: 0,
},
pm10: 5,
runningTime: 0,
sn: "125630100924141",
wearRate: 0,
enabled: true,
},
},
id: "avo_jggv6bsf211",
tp: "20.6",
pm10: 5,
type: "monitor",
}
例如,我需要:
str = 'ts, pr, pm25, co2, hm, "m.isConnected, m. wifiBm, pm1, s.0.runningTime, s.0.sn, ...'
这就是我现在的代码:
guessHeader(object: MeasurementModel | any, parentKey?: string): string[] {
// Looping on object's keys
Object.keys(object).forEach(key => {
if (typeof object[key] === 'object' && key !== 'ts') {
// If the object is an array recurse in it
return this.guessHeader(object[key], key)
} else {
// If we have a parentKey keep header as
if (parentKey)
this.header.push(`${parentKey}.${key}`)
else
this.header.push(key)
}
})
return this.header
}
它适用于密钥 m,我有 m.isConnected 和 m.wifiBm 但对于 s.0.runningTime 我只有 0.runningTime。此外,此对象可以更改并嵌套得更多。我需要找到一种适用于任何情况的方法。我试图将键保存在一个数组中,然后解析它们但失败了。
问题在这里:
// If the object is an array recurse in it
return this.guessHeader(object[key], key)
这应该是
this.header.push(...this.guessHeader(object[key], parentKey === undefined ? key : `${parentKey}.${key}`))
此外,typeof null === 'object'
,因此在将 object[key]
传递给 guessHeader
.[=28 之前,您还应该检查 object[key]
是否为非空(例如 typeof object[key] === 'object' && object[key]
) =]
还有一点就是MeasurementModel | any
和any
是一样的。避免使用类型安全的 any
和
guessHeader
的实现可能如下所示:
guessHeader(object: object, parentKey?: string): string[] {
Object.keys(object).forEach(key => {
const newKey = parentKey === undefined ? key : `${parentKey}.${key}`
const value = (object as Record<string, unknown>)[key]
if (typeof value === 'object' && value && key !== 'ts')
this.header.push(...this.guessHeader(value, newKey))
else
this.header.push(newKey)
})
return this.header
}
就我个人而言,我会使用 Object.entries
并执行如下操作:
const guessHeader = (object: object, acc = ''): string =>
Object.entries(object)
.map(([key, value]: [string, unknown]) =>
// It looks like you don't want to recurse into the ts key,
// which is why I used key !== 'ts'
// I'm guessing ts might be a Date; you could avoid recursing into
// all Dates by doing
// typeof value == 'object' && value && !(value instanceof Date)
key !== 'ts' && typeof value === 'object' && value
? guessHeader(value, `${acc}${key}.`)
: acc + key
)
.join(', ')
const input = {ts: '2021-05-06T11:06:18Z', pr: 94665, pm25: 5, co2: 1605, hm: 32, m: {isConnected: true, wifidBm: 0}, pm1: 5, s: {0: {runningTime: 0, sn: '05064906137109790000', wearRate: 0, enabled: true, co2: 1605}, 1: {enabled: false, sn: '125630092251006'}, 2: {enabled: false, sn: '05064906137109450000'}, 3: {fanStatus: 0, pm25: 5, pm1: '5', e: {rawSensorError: 0}, pm10: 5, runningTime: 0, sn: '125630100924141', wearRate: 0, enabled: true}}, id: 'avo_jggv6bsf211', tp: '20.6', pm10: 5, type: 'monitor'}
// same as above code block
const guessHeader = (object, acc = '') => Object.entries(object).map(([key, value]) => key !== 'ts' && typeof value === 'object' && value ? guessHeader(value, `${acc}${key}.`) : acc + key).join(', ')
console.log(guessHeader(input))