我目前正在与 redux reducer 作斗争。
//backend response
const response = {
data: {
results: {
222: {
items: ['id1', 'id3']
},
333: {
items: ['id2', 'id4', 'id999 (UNKNOWN)']
}
}
}
};
//currently saved in redux state
const stateItems = [
{
id: 'id1',
name: 'item ONE'
}, {
id: 'id2',
name: 'item TWO'
}, {
id: 'id3',
name: 'item THREE'
}, {
id: 'id4',
name: 'item FOUR'
}, {
id: 'id5',
name: 'item FIVE (UNUSED)'
}, {
id: 'id6',
name: 'item SIX (UNUSED)'
}
];
//converting items: ['ids'] => items: [{id: 'id', name: 'itemName'}]
const result = Object.values(response.data.results).map((keys, index, array) => {
keys.items = keys.items.map(itemId => {
return stateItems[stateItems.findIndex(x => x.id === itemId)];
});
return response.data.results;
});
//final result should be:
const expectedFinalResult = {
222: {items: [{id: 'id1', name: 'item ONE'}, {id: 'id3', name: 'item THREE'}]},
333: {items: [{id: 'id2', name: 'item TWO'}, {id: 'id4', name: 'item FOUR'}]}
};
//both should be equal:
console.log(JSON.stringify(expectedFinalResult));
console.log(JSON.stringify(result));
console.log('same result: ' + JSON.stringify(result) === JSON.stringify(expectedFinalResult));
我已经没有想法了,如何实现它。 UNUSED
和 UNKNOWN
也应该被过滤掉。因此本例中的最终结果就像 const ExpectedFinalResult 中的那样。目前,const result
返回错误结果。
希望有人有更好的想法或更好的方法。
谢谢
最佳答案
Object.entries
的方向是正确的。您可以使用解构来挑选键('222'
、'333'
)和值对象的 items
数组,然后使用该数组过滤 stateItems
并为结果中的每个条目生成 items
数组:
const result = {};
for (const [key, {items}] of Object.entries(response.data.results)) {
result[key] = {
items: stateItems.filter(item => items.includes(item.id))
};
}
实例:
//backend response
const response = {
data: {
results: {
222: {
items: ['id1', 'id3']
},
333: {
items: ['id2', 'id4', 'id999 (UNKNOWN)']
}
}
}
};
//currently saved in redux state
const stateItems = [
{
id: 'id1',
name: 'item ONE'
}, {
id: 'id2',
name: 'item TWO'
}, {
id: 'id3',
name: 'item THREE'
}, {
id: 'id4',
name: 'item FOUR'
}, {
id: 'id5',
name: 'item FIVE (UNUSED)'
}, {
id: 'id6',
name: 'item SIX (UNUSED)'
}
];
const result = {};
for (const [key, {items}] of Object.entries(response.data.results)) {
result[key] = {
items: stateItems.filter(item => items.includes(item.id))
};
}
//final result should be:
const expectedFinalResult = {
222: {items: [{id: 'id1', name: 'item ONE'}, {id: 'id3', name: 'item THREE'}]},
333: {items: [{id: 'id2', name: 'item TWO'}, {id: 'id4', name: 'item FOUR'}]}
};
//both should be equal:
console.log(JSON.stringify(result, null, 4));
.as-console-wrapper {
max-height: 100% !important;
}
这会多次遍历stateItems
。如果它或 response.data.results
真的非常非常大(比如数十万),那么可能值得按 id
对 stateItem
进行 Map
来代替:
// Create map of state items (only once each time stateItems changes):
const stateItemMap = new Map(stateItems.map(item => [item.id, item]));
// Map results (each time you get results):
const result = {};
for (const [key, {items}] of Object.entries(response.data.results)) {
result[key] = {
items: items.map(id => stateItemMap.get(id))
};
}
实例:
//backend response
const response = {
data: {
results: {
222: {
items: ['id1', 'id3']
},
333: {
items: ['id2', 'id4', 'id999 (UNKNOWN)']
}
}
}
};
//currently saved in redux state
const stateItems = [
{
id: 'id1',
name: 'item ONE'
}, {
id: 'id2',
name: 'item TWO'
}, {
id: 'id3',
name: 'item THREE'
}, {
id: 'id4',
name: 'item FOUR'
}, {
id: 'id5',
name: 'item FIVE (UNUSED)'
}, {
id: 'id6',
name: 'item SIX (UNUSED)'
}
];
// Create map of state items (only once each time stateItems changes):
const stateItemMap = new Map(stateItems.map(item => [item.id, item]));
// Map results (each time you get results):
const result = {};
for (const [key, {items}] of Object.entries(response.data.results)) {
result[key] = {
items: items.map(id => stateItemMap.get(id))
};
}
//final result should be:
const expectedFinalResult = {
222: {items: [{id: 'id1', name: 'item ONE'}, {id: 'id3', name: 'item THREE'}]},
333: {items: [{id: 'id2', name: 'item TWO'}, {id: 'id4', name: 'item FOUR'}]}
};
//both should be equal:
console.log(JSON.stringify(result, null, 4));
.as-console-wrapper {
max-height: 100% !important;
}
关于javascript - 将嵌套数组转换为对象,将数组索引与对象 ID 匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54269143/