我已经使用循环实现了以下问题的解决方案,但是我敢肯定有更好的方法。考虑以下数据结构:
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"
}
}
]
}
]
我想学习最有效的方法,将其简化为仅包含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" }
}
我有一个局部解决方案,它返回每个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?
}, {})
在这里可以选择递归还是一种更好的方法?
答案 0 :(得分:2)
下面的代码首先对嵌套的flatMap
数组执行sources
操作,然后将所有内容简化为所需的结果对象:
const result = arr.reduce((a, {sources}) => [...a, ...sources], [])
.reduce((a, {uri, state}) => ({...a, [uri]: state}), {});
完整代码段:
const 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"
}
}
]
}
];
const result = arr.reduce((a, {sources}) => [...a, ...sources], [])
.reduce((a, {uri, state}) => ({...a, [uri]: state}), {});
console.log(result)
答案 1 :(得分:2)
您可以减少外部数组并迭代sources
并更新对象作为结果集。
var data = [{ 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" } }] }],
stateMap = data.reduce(
(o, { sources }) => (sources.forEach(({ uri, state }) => o[uri] = state), o),
Object.create(null)
);
console.log(stateMap);
.as-console-wrapper { max-height: 100% !important; top: 0; }
在这里可以选择递归还是一种更好的方法?
不,因为您只有一个嵌套级别。
答案 2 :(得分:1)
您可以使用嵌套的reduce来从列表中的项目中获取uri映射,另一种用于获取源映射的值。
const mappedArray = arr.reduce((acc, item) => ({
...acc,
...item.sources.reduce((accSource, itemSource) => ({
...accSource,
[itemSource.uri]: itemSource.state,
}), {})
}), {})
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"
}
}
]
}
]
const mappedArray = arr.reduce((acc, item) => ({
...acc,
...item.sources.reduce((accSource, itemSource) => ({
...accSource,
[itemSource.uri]: itemSource.state,
}), {})
}), {})
console.log(mappedArray)