简体   繁体   English

基于月份的对象值总和数组 - ReactJS

[英]Sum array of objects value based on month - ReactJS

So first of all, because I am using a ChartJS I need to generate an array of months.所以首先,因为我使用的是ChartJS ,所以我需要生成一个月份数组。 The creation is looking like this:创作看起来像这样:

const [generatedMonths, setGeneratedMonths] = useState<string[]>([])
const [totalValues, setTotalValues] = useState<number[]>([])

const months = []
const dateStart = moment()
const dateEnd = moment().subtract(11, 'month')

while (dateEnd.isBefore(dateStart, 'day')) {
    months.push(dateEnd.format('MMM'))
    dateEnd.add(1, 'month')
}
months.push(dateEnd.format('MMM'))

setGeneratedMonths(months)

After that i receive my data like this:之后我收到这样的数据:

  const myArray = [
    {date: "2022-04-13", vat_percentages: {21: 92.31}, total: 92.31}
    {date: "2022-05-04", vat_percentages: {21: 21.24}, total: 21.24}
    {date: "2022-05-05", vat_percentages: {21: 47.41}, total: 47.41}
    ]

Then in my useEffect hook i am performing the sum:然后在我的useEffect挂钩中执行总和:

useEffect(() => {
    if (myArray.length > 0) {
        const labelValues: number[] = generatedMonths.map(
            (label, index) => {
                const result = myArray.reduce((acc, curr) => {
                    const foundItem = acc.find(
                        (item) => item.date.format('MMM') === label
                    )

                    if (foundItem) {
                        foundItem.total += curr.total
                    } else {
                        acc.push(curr)
                    }

                    return acc
                }, [])
            }
        )

      setTotalValues(labelValues)
    }


},[myArray])

So the final idea would be to have a sum for each month based on my find method based on the total value.所以最终的想法是根据我的基于total的查找方法对每个月进行汇总。 Like this:像这样:

console.log(totalValues)
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92.31, 68.65]

You can massively simplify the solution using the fact that values for month are always going to be between 1-12 (inclusive).您可以使用月份值始终介于 1-12(含)之间这一事实来极大地简化解决方案。 Therefore you can use an array of length 12 and use month - 1 as an index to update the sum for a given month.因此,您可以使用长度为 12 的数组并使用month - 1作为索引来更新给定月份的总和。

 const myArray = [{ date: "2022-04-13", vat_percentages: { 21: 92.31 }, total: 92.31 }, { date: "2022-05-04", vat_percentages: { 21: 21.24 }, total: 21.24 }, { date: "2022-05-05", vat_percentages: { 21: 47.41 }, total: 47.41 }] const labelValues = myArray.reduce((acc, curr) => { // parse a month to number eg "04" => 4 then substract 1 to get the index within the array 4 - 1 => 3 const idx = Number(curr.date.split("-")[1]) - 1; acc[idx] += curr.total; return acc }, new Array(12).fill(0)) console.log(labelValues)
 .as-console-wrapper { max-height: 100%;important: top; 0; }

The output should be interpreted as follows: output 应该解释如下:

0 (Jan) 0(一月) 1 (Feb) 1 (二月) 2 (Mar) 2 (三月) 3 (Apr) 3 (四月) 4 (May) 4(五月) 5 (Jun) 5(六月) 6 (Jul) 6(七月) 7 (Aug) 7(八月) 8 (Sep) 8 (九月) 9 (Oct) 9 (十月) 10 (Nov) 10 (十一月) 11 (De) 11 (德语)
0 0 0 0 0 0 92.31 92.31 68.64999999999999 68.64999999999999 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Edit编辑

To reflect your requirement of having to set the values at certain positions according to generatedMonths you could use simple modular arithmetic .为了反映您必须根据generatedMonths在某些位置设置值的要求,您可以使用简单的模块化算法

A position for a month is therefore obtained by (month + shiftValue) % 12 .因此,一个月的 position 是通过(month + shiftValue) % 12获得的。 To determine the shift value you just need to look at the first value in generatedMonths and lookup which month of the year that is.要确定班次值,您只需查看generatedMonths中的第一个值并查找一年中的哪个月份。 The rest works exactly like before: rest 的工作原理与之前完全相同:

 const myArray = [{ date: "2022-04-13", vat_percentages: { 21: 92.31 }, total: 92.31 }, { date: "2022-05-04", vat_percentages: { 21: 21.24 }, total: 21.24 }, { date: "2022-05-05", vat_percentages: { 21: 47.41 }, total: 47.41 }] // mapping of month to shift value const mapping = { Jan: 0, Feb: 11, Mar: 10, Apr: 9, May: 8, Jun: 7, Jul: 6, Aug: 5, Sep: 4, Oct: 3, Nov: 2, Dec: 1 }; // compute a shift value const generatedMonths = ["Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr", "May"] const shiftBy = mapping[generatedMonths[0]]; const labelValues = myArray.reduce((acc, curr) => { // parse a month to number eg "04" => 4 then substract 1 to get the index within the array 4 - 1 => 3 const idx = (Number(curr.date.split("-")[1]) + shiftBy - 1) % 12; acc[idx] += curr.total; return acc }, new Array(12).fill(0)) console.log(labelValues)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM