mer*_*ilj 5 javascript json data-structures
我已经用循环实现了以下问题的解决方案,但我确信有更好的方法。考虑这个数据结构:
let arr = [
{
"id": "000701",
"status": "No Source Info",
"sources": []
},
{
"id": "200101",
"status": "Good",
"sources": [
{
"center": "H2",
"uri": "237.0.1.133",
"program": 1,
"status": "Good",
"state": {
"authState": "authorized",
"lockState": "locked"
}
}
]
},
{
"id": "005306",
"status": "Good",
"sources": [
{
"center": "H1",
"uri": "237.0.6.5",
"program": 3,
"status": "Good",
"state": {
"authState": "authorized",
"lockState": "locked"
}
},
{
"center": "H1",
"uri": "237.0.6.25",
"program": 3,
"status": "Good",
"state": {
"authState": "authorized",
"lockState": "locked"
}
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
uri我想学习最有效的方法,将其简化为仅包含嵌套数组和state值的键值对的映射sources。最终结果应如下所示:
let stateMap = {
"237.0.1.133": { "authState": "authorized", "lockState": "locked" },
"237.0.6.5": { "authState": "authorized", "lockState": "locked" },
"237.0.6.25": { "authState": "authorized", "lockState": "locked" }
}
Run Code Online (Sandbox Code Playgroud)
我有一个部分解决方案,它返回每个数组的映射source,但我正在努力将其全部放入一个结构中。
let allStates = arr.reduce((acc, object) => {
if (object.sources.length) {
let sourceMap = object.sources.reduce((map, obj) => {
map[obj.uri] = obj.state
return map
}, {})
acc[acc.length] = sourceMap
return acc
}
// delete all unused keys and somehow flatten the objects?
}, {})
Run Code Online (Sandbox Code Playgroud)
递归是这里的一个选择还是更好的方法?
下面的代码首先flatMap对嵌套sources数组执行操作,然后将所有内容缩减为所需的结果对象:
const result = arr.reduce((a, {sources}) => [...a, ...sources], [])
.reduce((a, {uri, state}) => ({...a, [uri]: state}), {});
Run Code Online (Sandbox Code Playgroud)
完整片段:
const result = arr.reduce((a, {sources}) => [...a, ...sources], [])
.reduce((a, {uri, state}) => ({...a, [uri]: state}), {});
Run Code Online (Sandbox Code Playgroud)