如何拆分对象数组并提取特定键,同时添加0以填充到特定长度?

huangapple go评论76阅读模式
英文:

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 不应该是一个映射,而应该是 firstItemdata 的切片。你通过使用映射来获取 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 &lt; result[0].data.length / 4; ++k){
    newstack.push({
        data:Array.from({...result[0].data.slice(4 * k),length:4},(v,i)=&gt;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

&lt;!-- 开始代码片段: js 显示: false 控制台: true Babel: false --&gt;

&lt;!-- 语言: lang-js --&gt;

    let arr = [{
      &quot;data&quot;: [5, 2, 7, 2, 4, 2],
      &quot;date&quot;: {
        &quot;begin&quot;: &quot;03.07.&quot;,
        &quot;beginYear&quot;: &quot;2023&quot;,
        &quot;end&quot;: &quot;10.07.&quot;,
        &quot;endYear&quot;: &quot;2023&quot;,
        &quot;timestamp&quot;: 1688335200000
      }
    }, {
      &quot;data&quot;: [5, 2, 7, 2, 4, 2],
      &quot;date&quot;: {
        &quot;begin&quot;: &quot;26.06.&quot;,
        &quot;beginYear&quot;: &quot;2023&quot;,
        &quot;end&quot;: &quot;03.07.&quot;,
        &quot;endYear&quot;: &quot;2023&quot;,
        &quot;timestamp&quot;: 1687730400000
      }
    }, {
      &quot;data&quot;: [5, 2],
      &quot;date&quot;: {
        &quot;begin&quot;: &quot;19.06.&quot;,
        &quot;beginYear&quot;: &quot;2023&quot;,
        &quot;end&quot;: &quot;26.06.&quot;,
        &quot;endYear&quot;: &quot;2023&quot;,
        &quot;timestamp&quot;: 1687125600000
      }
    }, {
      &quot;data&quot;: [5, 2, 7, 2, 4, 2],
      &quot;date&quot;: {
        &quot;begin&quot;: &quot;12.06.&quot;,
        &quot;beginYear&quot;: &quot;2023&quot;,
        &quot;end&quot;: &quot;19.06.&quot;,
        &quot;endYear&quot;: &quot;2023&quot;,
        &quot;timestamp&quot;: 1686520800000
      }
    }, {
      &quot;data&quot;: [5, 2, 7, 2, 4, 2],
      &quot;date&quot;: {
        &quot;begin&quot;: &quot;05.06.&quot;,
        &quot;beginYear&quot;: &quot;2023&quot;,
        &quot;end&quot;: &quot;12.06.&quot;,
        &quot;endYear&quot;: &quot;2023&quot;,
        &quot;timestamp&quot;: 1685916000000
      }
    }, {
      &quot;data&quot;: [5],
      &quot;date&quot;: {
        &quot;begin&quot;: &quot;29.05.&quot;,
        &quot;beginYear&quot;: &quot;2023&quot;,
        &quot;end&quot;: &quot;05.06.&quot;,
        &quot;endYear&quot;: &quot;2023&quot;,
        &quot;timestamp&quot;: 1685311200000
      }
    }];

    arr.map((e) =&gt; {
      if (e.data.length &gt; 4) {
        e.data = e.data.slice(0, 4);
      } else {
        let length = 4 - e.data.length;
        for (let i = 0; i &lt; length; i++) {
          e.data.push(0);
        }
      }

    })
    console.log(arr);

&lt;!-- 结束代码片段 --&gt;
英文:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let arr = [{
  &quot;data&quot;: [5, 2, 7, 2, 4, 2],
  &quot;date&quot;: {
    &quot;begin&quot;: &quot;03.07.&quot;,
    &quot;beginYear&quot;: &quot;2023&quot;,
    &quot;end&quot;: &quot;10.07.&quot;,
    &quot;endYear&quot;: &quot;2023&quot;,
    &quot;timestamp&quot;: 1688335200000
  }
}, {
  &quot;data&quot;: [5, 2, 7, 2, 4, 2],
  &quot;date&quot;: {
    &quot;begin&quot;: &quot;26.06.&quot;,
    &quot;beginYear&quot;: &quot;2023&quot;,
    &quot;end&quot;: &quot;03.07.&quot;,
    &quot;endYear&quot;: &quot;2023&quot;,
    &quot;timestamp&quot;: 1687730400000
  }
}, {
  &quot;data&quot;: [5, 2],
  &quot;date&quot;: {
    &quot;begin&quot;: &quot;19.06.&quot;,
    &quot;beginYear&quot;: &quot;2023&quot;,
    &quot;end&quot;: &quot;26.06.&quot;,
    &quot;endYear&quot;: &quot;2023&quot;,
    &quot;timestamp&quot;: 1687125600000
  }
}, {
  &quot;data&quot;: [5, 2, 7, 2, 4, 2],
  &quot;date&quot;: {
    &quot;begin&quot;: &quot;12.06.&quot;,
    &quot;beginYear&quot;: &quot;2023&quot;,
    &quot;end&quot;: &quot;19.06.&quot;,
    &quot;endYear&quot;: &quot;2023&quot;,
    &quot;timestamp&quot;: 1686520800000
  }
}, {
  &quot;data&quot;: [5, 2, 7, 2, 4, 2],
  &quot;date&quot;: {
    &quot;begin&quot;: &quot;05.06.&quot;,
    &quot;beginYear&quot;: &quot;2023&quot;,
    &quot;end&quot;: &quot;12.06.&quot;,
    &quot;endYear&quot;: &quot;2023&quot;,
    &quot;timestamp&quot;: 1685916000000
  }
}, {
  &quot;data&quot;: [5],
  &quot;date&quot;: {
    &quot;begin&quot;: &quot;29.05.&quot;,
    &quot;beginYear&quot;: &quot;2023&quot;,
    &quot;end&quot;: &quot;05.06.&quot;,
    &quot;endYear&quot;: &quot;2023&quot;,
    &quot;timestamp&quot;: 1685311200000
  }
}];

arr.map((e) =&gt; {
  if (e.data.length &gt; 4) {
    e.data = e.data.slice(0, 4);
  } else {
    let length = 4 - e.data.length;
    for (let i = 0; i &lt; length; i++) {
      e.data.push(0);
    }
  }

})
console.log(arr);

<!-- end snippet -->

答案3

得分: 0

这是一个可配置的解决方案。您可以指定每个条目的数据项数目 (dataLength),更改每个条目中 beginend 日期之间的差异 (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 = [
{&quot;data&quot;: [5, 2, 7, 2, 4, 2], &quot;date&quot;: {&quot;begin&quot;: &quot;03.07.&quot;, &quot;beginYear&quot;: &quot;2023&quot;, &quot;end&quot;: &quot;10.07.&quot;, &quot;endYear&quot;: &quot;2023&quot;, &quot;timestamp&quot;: 1688335200000}},
{&quot;data&quot;: [5, 2, 7, 2, 4, 2], &quot;date&quot;: {&quot;begin&quot;: &quot;26.06.&quot;, &quot;beginYear&quot;: &quot;2023&quot;, &quot;end&quot;: &quot;03.07.&quot;, &quot;endYear&quot;: &quot;2023&quot;, &quot;timestamp&quot;: 1687730400000}},
{&quot;data&quot;: [5, 2, 7, 2, 4, 2], &quot;date&quot;: {&quot;begin&quot;: &quot;19.06.&quot;, &quot;beginYear&quot;: &quot;2023&quot;, &quot;end&quot;: &quot;26.06.&quot;, &quot;endYear&quot;: &quot;2023&quot;, &quot;timestamp&quot;: 1687125600000}},
{&quot;data&quot;: [5, 2, 7, 2, 4, 2], &quot;date&quot;: {&quot;begin&quot;: &quot;12.06.&quot;, &quot;beginYear&quot;: &quot;2023&quot;, &quot;end&quot;: &quot;19.06.&quot;, &quot;endYear&quot;: &quot;2023&quot;, &quot;timestamp&quot;: 1686520800000}},
{&quot;data&quot;: [5, 2, 7, 2, 4, 2], &quot;date&quot;: {&quot;begin&quot;: &quot;05.06.&quot;, &quot;beginYear&quot;: &quot;2023&quot;, &quot;end&quot;: &quot;12.06.&quot;, &quot;endYear&quot;: &quot;2023&quot;, &quot;timestamp&quot;: 1685916000000}},
{&quot;data&quot;: [5, 2, 7, 2, 4, 2], &quot;date&quot;: {&quot;begin&quot;: &quot;29.05.&quot;, &quot;beginYear&quot;: &quot;2023&quot;, &quot;end&quot;: &quot;05.06.&quot;, &quot;endYear&quot;: &quot;2023&quot;, &quot;timestamp&quot;: 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}) =&gt; {
let ts = date.timestamp;
for (let dataOffset = 0; dataOffset &lt; 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 &lt; dataLength) {
lastData.push(0);
}
});
return result;
}
console.log(processArray(source, 4, 7, 28));

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月2日 15:01:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76387851.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定