javascript - 在reduce的对象中设置一个特定键的属性就是为所有属性设置它
问题描述
好吧,我真的不知道这里发生了什么。我假设它是某种参考问题?但我不知道如何解决它或导致它的原因。
总而言之,我有一个对象列表,以及一个预先填充的对象,以确保我拥有对象中所有键的数据。
我需要遍历这个对象列表,并通过使用元数据对象中的 timeframeId 和数据对象中的 id,我想将整个数据对象分配给预填充对象中相应的 timeframeId 和 id 层次结构。
出于某种原因,所有data
属性都被覆盖到最后一行data
。
我已经链接了一个 repl,所以您可以自己查看:https ://repl.it/@ThomasVermeers1/UnwrittenNoisyFirm#index.js
但我的代码如下:
const buildSegmentsFromRows = (rows, timeframeMetadata, defaultSegmentData) => {
// Prepopulate object to make sure every timeframe has a 'hello' key in it with some data
const emptySegments = timeframeMetadata.reduce((segmentMap, metadata) => {
segmentMap[metadata.timeframeId] = {
metadata,
segments: defaultSegmentData,
};
return segmentMap;
}, {});
// Now simply just loop over the rows, and set [row.metadata.timeframeId].segments[row.data.id] to row.data
const segments = rows.reduce((partialSegments, row) => {
const { timeframeId } = row.metadata;
const { id } = row.data;
/**
* This is the line where everything goes wrong
*/
partialSegments[timeframeId].segments[id] = row.data;
return partialSegments;
}, emptySegments);
return segments;
};
const rows = [
{
metadata: { timeframeId: '20202_01' },
data: {
'id': 'hello', 'value': 15
}
},
{
metadata: { timeframeId: '20202_02' },
data: {
'id': 'hello', 'value': 10
}
}
]
const timeframemetadata = [
{ timeframeId: '20202_01'},
{ timeframeId: '20202_02'}
]
const defaultSegmentData = {
'hello': {
'id': 'hello',
}
}
console.log(JSON.stringify(buildSegmentsFromRows(rows, timeframemetadata, defaultSegmentData), null, 2))
我期待最终结果是:
{
"20202_01": {
"metadata": {
"timeframeId": "20202_01"
},
"segments": {
"hello": {
"id": "hello",
"value": 15
}
}
},
"20202_02": {
"metadata": {
"timeframeId": "20202_02"
},
"segments": {
"hello": {
"id": "hello",
"value": 10
}
}
}
}
但相反,在所有情况下都value
设置为。10
我在想它是因为我们将属性设置为row.data
,这是一个参考,并且在每次调用时都会更新?但我在这里完全不知所措。
解决方案
问题是您为segments
列表中的每个都引用了相同的对象。
因此,更改 的值segments[id]
将更新defaultSegmentData
,从而导致每个对 的引用也defaultSegmentData
发生变化。
const emptySegments = timeframeMetadata.reduce((segmentMap, metadata) => {
segmentMap[metadata.timeframeId] = {
metadata,
segments: defaultSegmentData, // Everything goes wrong here.
};
return segmentMap;
}, {});
此问题的一个简单解决方案是在创建时避免使用对对象的相同引用segmentMap
:
const emptySegments = timeframeMetadata.reduce((segmentMap, metadata) => {
segmentMap[metadata.timeframeId] = {
metadata,
/** Or whatever default value you want.
* Just make sure to create a new instance of it for each call.
*/
segments: {},
};
return segmentMap;
}, {});
推荐阅读
- sql-server - 有什么方法可以将同义词表添加到 SQL Server 中的数据库图表中?
- java - 使用 JMS 服务引用创建 Spring 上下文时出现异常
- python - 在 docker 中找不到 Gunicorn 模块
- google-cloud-platform - 无法删除 Dialogflow 留置权
- wordpress - Elementor 单击链接 URL 时关闭 Popupmaker
- javascript - 拖放:dragLeave 在动态添加的元素上触发
- javascript - 用html标签封装元素
- angular - 如何使用纱线离线标志使用 ng 命令创建新的 Angular 应用程序?
- r - R错误:优化导致“未使用的参数(x)”
- java - 我的解决方法出错并且不打印真假