英文:
How can I split an array of objects and extract specific keys while adding 0s to fill up to a specific length?
问题
我的对象数组如下所示:
[{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "26.06.", "beginYear": "2023", "end": "03.07.", "endYear": "2023", "timestamp": 1687730400000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "19.06.", "beginYear": "2023", "end": "26.06.", "endYear": "2023", "timestamp": 1687125600000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "12.06.", "beginYear": "2023", "end": "19.06.", "endYear": "2023", "timestamp": 1686520800000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "05.06.", "beginYear": "2023", "end": "12.06.", "endYear": "2023", "timestamp": 1685916000000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "29.05.", "beginYear": "2023", "end": "05.06.", "endYear": "2023", "timestamp": 1685311200000}}]
我想遍历数组,检查"data"键是否包含超过4个数字,如果是的话,我想提取前4个数字(每个对象中的"data"键都是相同的),并将它们放入一个新的对象键"data"中,日期键应该看起来像原始数组的第一项。数据键的其余部分(在这个示例中是[4,2])应该放入一个新的数组中,直到"data"的长度为4为止。这个新数组的日期键应该包含从第一个日期开始的4周日期。
我想修改它,使结果如下所示:
[{
data: [ 5, 2, 7, 2 ],
date: {
begin: '29.05.',
beginYear: '2023',
end: '05.06.',
endYear: '2023',
timestamp: 1685311200000
}
},
{
data: [4, 2, 0, 0 ],
date: {
begin: '26.06.',
beginYear: '2023',
end: '03.07.',
endYear: '2023',
timestamp: 1687730400000
}
}
]
如果"data"键包含更多的数字,逻辑也应适用。
我尝试了好几次,但不知何故它没有按计划进行。
const fourStack = []
const firstFourItems = result.slice(0, 4)
const restItems = result.slice(4)
const firstItem = firstFourItems[0]
const newData = firstFourItems.map((item) => item.data.slice(0, 4))
const newObj = {
data: newData,
date: {
begin: firstItem.date.begin,
beginYear: firstItem.date.beginYear,
end: firstItem.date.end,
endYear: firstItem.date.endYear,
timestamp: firstItem.date.timestamp
}
}
fourStack.push(newObj)
restItems.forEach((item) => {
fourStack.push({
data: item.data.slice(0, 4),
date: {
begin: newObj.date.begin,
beginYear: newObj.date.beginYear,
end: newObj.date.end,
endYear: newObj.date.endYear,
timestamp: newObj.date.timestamp
}
})
})
它给了我一个不是我想要的结果。相反,它给了我这个:
[{"data": [[Array], [Array], [Array], [Array]], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}}, {"data": [5, 2, 7, 2], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}}, {"data": [5, 2, 7, 2], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}}]
英文:
My array of objects looks like this:
[{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "26.06.", "beginYear": "2023", "end": "03.07.", "endYear": "2023", "timestamp": 1687730400000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "19.06.", "beginYear": "2023", "end": "26.06.", "endYear": "2023", "timestamp": 1687125600000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "12.06.", "beginYear": "2023", "end": "19.06.", "endYear": "2023", "timestamp": 1686520800000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "05.06.", "beginYear": "2023", "end": "12.06.", "endYear": "2023", "timestamp": 1685916000000}}, {"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "29.05.", "beginYear": "2023", "end": "05.06.", "endYear": "2023", "timestamp": 1685311200000}}]
I want to map through the array, checking if the data key contains more than 4 numbers and if so, I want to extract the first 4 numbers (each data key is the same in all objects) and put it into a new object key "data" and the date key should look like the first item of the original array. The rest of the data key (in this example [4,2] should go into a new array that will be filled up with 0s until the data's length is 4. The date key of this should contain the date in 4 weeks starting from the first date.
I want to modify it so the result will be like this:
[{
data: [ 5, 2, 7, 2 ],
date: {
begin: '29.05.',
beginYear: '2023',
end: '05.06.',
endYear: '2023',
timestamp: 1685311200000
}
},
{
data: [4, 2, 0, 0 ],
date: {
begin: '26.06.',
beginYear: '2023',
end: '03.07.',
endYear: '2023',
timestamp: 1687730400000
}
}
]
The logic should also applicable if the data key contains more numbers
I tried it several times but somehow it doesn't as planned.
const fourStack = []
const firstFourItems = result.slice(0, 4)
const restItems = result.slice(4)
const firstItem = firstFourItems[0]
const newData = firstFourItems.map((item) => item.data.slice(0, 4))
const newObj = {
data: newData,
date: {
begin: firstItem.date.begin,
beginYear: firstItem.date.beginYear,
end: firstItem.date.end,
endYear: firstItem.date.endYear,
timestamp: firstItem.date.timestamp
}
}
fourStack.push(newObj)
restItems.forEach((item) => {
fourStack.push({
data: item.data.slice(0, 4),
date: {
begin: newObj.date.begin,
beginYear: newObj.date.beginYear,
end: newObj.date.end,
endYear: newObj.date.endYear,
timestamp: newObj.date.timestamp
}
})
})
It gives me, not the result I want. Instead, it gives me this:
[{"data": [[Array], [Array], [Array], [Array]], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}}, {"data": [5, 2, 7, 2], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}}, {"data": [5, 2, 7, 2], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}}]
答案1
得分: 1
newData
不应该是一个映射,而应该是 firstItem
的 data
的切片。你通过使用映射来获取 firsFourItems
中所有项目的所有 data
。
在你的 forEach
中,你正在推送相同的 date
,而你使用的 data
仍然是原始 data
键的前四个。它应该使用初始 data
的切片,并填充 0 直到长度为 4。
考虑以下代码:
for (var k = 0; k < result[0].data.length / 4; ++k) {
newstack.push({
data: Array.from({ ...result[0].data.slice(4 * k), length: 4 }, (v, i) => v ?? 0),
date: result[k * 4].date // 编辑:因为你想要按日期排序,所以先排序日期,然后获取排序后数组的 [k*4] 位置
})
}
英文:
newData
shouldn't be a map, but a slice of the data
of firstItem
. You're getting all the data
of all items in firsFourItems
by doing a map.
You're pushing the same date
in your forEach
and the data
you're using is still the first four of the original data
key. It should use a slice of the initial data
and filled with 0 until the length is 4.
Consider:
for(var k = 0; k < result[0].data.length / 4; ++k){
newstack.push({
data:Array.from({...result[0].data.slice(4 * k),length:4},(v,i)=>v??0),
date: result[k*4].date // Edit: since you want the date sorted, sort the dates then get the [k*4] of the sorted array
})
}
答案2
得分: 1
<!-- 开始代码片段: js 显示: false 控制台: true Babel: false -->
<!-- 语言: lang-js -->
let arr = [{
"data": [5, 2, 7, 2, 4, 2],
"date": {
"begin": "03.07.",
"beginYear": "2023",
"end": "10.07.",
"endYear": "2023",
"timestamp": 1688335200000
}
}, {
"data": [5, 2, 7, 2, 4, 2],
"date": {
"begin": "26.06.",
"beginYear": "2023",
"end": "03.07.",
"endYear": "2023",
"timestamp": 1687730400000
}
}, {
"data": [5, 2],
"date": {
"begin": "19.06.",
"beginYear": "2023",
"end": "26.06.",
"endYear": "2023",
"timestamp": 1687125600000
}
}, {
"data": [5, 2, 7, 2, 4, 2],
"date": {
"begin": "12.06.",
"beginYear": "2023",
"end": "19.06.",
"endYear": "2023",
"timestamp": 1686520800000
}
}, {
"data": [5, 2, 7, 2, 4, 2],
"date": {
"begin": "05.06.",
"beginYear": "2023",
"end": "12.06.",
"endYear": "2023",
"timestamp": 1685916000000
}
}, {
"data": [5],
"date": {
"begin": "29.05.",
"beginYear": "2023",
"end": "05.06.",
"endYear": "2023",
"timestamp": 1685311200000
}
}];
arr.map((e) => {
if (e.data.length > 4) {
e.data = e.data.slice(0, 4);
} else {
let length = 4 - e.data.length;
for (let i = 0; i < length; i++) {
e.data.push(0);
}
}
})
console.log(arr);
<!-- 结束代码片段 -->
英文:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let arr = [{
"data": [5, 2, 7, 2, 4, 2],
"date": {
"begin": "03.07.",
"beginYear": "2023",
"end": "10.07.",
"endYear": "2023",
"timestamp": 1688335200000
}
}, {
"data": [5, 2, 7, 2, 4, 2],
"date": {
"begin": "26.06.",
"beginYear": "2023",
"end": "03.07.",
"endYear": "2023",
"timestamp": 1687730400000
}
}, {
"data": [5, 2],
"date": {
"begin": "19.06.",
"beginYear": "2023",
"end": "26.06.",
"endYear": "2023",
"timestamp": 1687125600000
}
}, {
"data": [5, 2, 7, 2, 4, 2],
"date": {
"begin": "12.06.",
"beginYear": "2023",
"end": "19.06.",
"endYear": "2023",
"timestamp": 1686520800000
}
}, {
"data": [5, 2, 7, 2, 4, 2],
"date": {
"begin": "05.06.",
"beginYear": "2023",
"end": "12.06.",
"endYear": "2023",
"timestamp": 1685916000000
}
}, {
"data": [5],
"date": {
"begin": "29.05.",
"beginYear": "2023",
"end": "05.06.",
"endYear": "2023",
"timestamp": 1685311200000
}
}];
arr.map((e) => {
if (e.data.length > 4) {
e.data = e.data.slice(0, 4);
} else {
let length = 4 - e.data.length;
for (let i = 0; i < length; i++) {
e.data.push(0);
}
}
})
console.log(arr);
<!-- end snippet -->
答案3
得分: 0
这是一个可配置的解决方案。您可以指定每个条目的数据项数目 (dataLength
),更改每个条目中 begin
和 end
日期之间的差异 (daysDelay
),并设置从同一初始条目获取的后续条目的 begin
日期之间的差异 (daysOffset
)。
以下是代码部分,不需要翻译:
let source = [
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "26.06.", "beginYear": "2023", "end": "03.07.", "endYear": "2023", "timestamp": 1687730400000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "19.06.", "beginYear": "2023", "end": "26.06.", "endYear": "2023", "timestamp": 1687125600000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "12.06.", "beginYear": "2023", "end": "19.06.", "endYear": "2023", "timestamp": 1686520800000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "05.06.", "beginYear": "2023", "end": "12.06.", "endYear": "2023", "timestamp": 1685916000000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "29.05.", "beginYear": "2023", "end": "05.06.", "endYear": "2023", "timestamp": 1685311200000}}
];
function processArray (source, dataLength, daysDelay, daysOffset) {
function getTimezoneOffset (obj) {
let year = +obj.beginYear;
let month = +obj.begin.slice(3, 5) - 1;
let day = +obj.begin.slice(0, 2);
return Date.UTC(year, month, day) - obj.timestamp;
}
function getDDMM (date) {
let DD = (date.getUTCDate() + 100).toString().slice(1);
let MM = (date.getUTCMonth() + 101).toString().slice(1);
return `${DD}.${MM}.`;
}
const result = [];
const msDay = 1000 * 60 * 60 * 24;
const msDaysDelay = daysDelay * msDay;
const msDaysOffset = daysOffset * msDay;
source.forEach(({data, date}) => {
let ts = date.timestamp;
for (let dataOffset = 0; dataOffset < data.length; dataOffset += dataLength) {
let msTimezoneOffset = getTimezoneOffset(date);
let dateCurrent = new Date(ts + msTimezoneOffset);
let dateNext = new Date(ts + msTimezoneOffset + msDaysDelay);
result.push({
data: data.slice(dataOffset, dataOffset + dataLength),
date: {
begin: getDDMM(dateCurrent),
beginYear: dateCurrent.getUTCFullYear(),
end: getDDMM(dateNext),
endYear: dateNext.getUTCFullYear(),
timestamp: ts
}
});
ts += msDaysOffset;
}
let lastData = result[result.length - 1].data;
while (lastData.length < dataLength) {
lastData.push(0);
}
});
return result;
}
console.log(processArray(source, 4, 7, 28));
希望这对您有所帮助!如果您有任何其他问题,请随时提出。
英文:
Here is a configurable solution. You can specify data items per entry (dataLength
), change the difference between begin
and end
dates within each entry (daysDelay
), and set the difference between begin
dates of subsequent entries obtained from the same initial entry (daysOffset
).
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let source = [
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "03.07.", "beginYear": "2023", "end": "10.07.", "endYear": "2023", "timestamp": 1688335200000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "26.06.", "beginYear": "2023", "end": "03.07.", "endYear": "2023", "timestamp": 1687730400000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "19.06.", "beginYear": "2023", "end": "26.06.", "endYear": "2023", "timestamp": 1687125600000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "12.06.", "beginYear": "2023", "end": "19.06.", "endYear": "2023", "timestamp": 1686520800000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "05.06.", "beginYear": "2023", "end": "12.06.", "endYear": "2023", "timestamp": 1685916000000}},
{"data": [5, 2, 7, 2, 4, 2], "date": {"begin": "29.05.", "beginYear": "2023", "end": "05.06.", "endYear": "2023", "timestamp": 1685311200000}}
];
function processArray (source, dataLength, daysDelay, daysOffset) {
function getTimezoneOffset (obj) {
let year = +obj.beginYear;
let month = +obj.begin.slice(3, 5) - 1;
let day = +obj.begin.slice(0, 2);
return Date.UTC(year, month, day) - obj.timestamp;
}
function getDDMM (date) {
let DD = (date.getUTCDate() + 100).toString().slice(1);
let MM = (date.getUTCMonth() + 101).toString().slice(1);
return `${DD}.${MM}.`;
}
const result = [];
const msDay = 1000 * 60 * 60 * 24;
const msDaysDelay = daysDelay * msDay;
const msDaysOffset = daysOffset * msDay;
source.forEach(({data, date}) => {
let ts = date.timestamp;
for (let dataOffset = 0; dataOffset < data.length; dataOffset += dataLength) {
let msTimezoneOffset = getTimezoneOffset(date);
let dateCurrent = new Date(ts + msTimezoneOffset);
let dateNext = new Date(ts + msTimezoneOffset + msDaysDelay);
result.push({
data: data.slice(dataOffset, dataOffset + dataLength),
date: {
begin: getDDMM(dateCurrent),
beginYear: dateCurrent.getUTCFullYear(),
end: getDDMM(dateNext),
endYear: dateNext.getUTCFullYear(),
timestamp: ts
}
});
ts += msDaysOffset;
}
let lastData = result[result.length - 1].data;
while (lastData.length < dataLength) {
lastData.push(0);
}
});
return result;
}
console.log(processArray(source, 4, 7, 28));
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论