-1

I have the data in the below format:

[
  {
    "Id": 1,
    "Title": "Title_1",
    "Positive": 5,
    "CreateTs": 1674231433428
  },
  {
    "Id": 2,
    "Title": "Title_1",
    "Positive": 8,
    "CreateTs": 1674288139000
  },
  {
    "Id": 3,
    "Title": "Title_2",
    "Positive": 5,
    "CreateTs": 1674633970000
  },
  
  {
    "Id": 4,
    "Title": "Title_1",
    "Positive": 12,
    "CreateTs": 1674649613000
  },
  
  {
    "Id": 5,
    "Title": "Title_1",
    "Positive": 10,
    "CreateTs": 1674649741000
  }
  ]

And I want the result as below:

  [
    // group by Title, and CreateTs in current week
    // Sum up the grouped number of Positive
    {
      "Title": "Title_1",
      "Positive_sum": 22
    },
    
    {
      "Title": "Title_2",
      "Positive_sum": 5
    }
  ]

I found similar question, but I am not able to interrupt it, it is too complex for me...

I tried to use array.slice method and get the first few terms. But it is not guarantee as the data is in different order every time. And I found some complex method on internet and it seems not work for me. So I would like to ask for help here.

  • shouldn't the sum of positives from the `Title_1` be `35` instead of `22`? – Chris G Jan 25 '23 at 13:00
  • Thanks for you question! I want the result is counted by the current week only, But is it possible? @ChrisG – happy happy Jan 25 '23 at 13:03
  • `CreateTs` is what defines current week right? or how do you know which ones belong to current week? I can see that all their values are different – Chris G Jan 25 '23 at 13:05
  • Does this answer your question? [Group objects by multiple properties in array then sum up their values](https://stackoverflow.com/questions/46794232/group-objects-by-multiple-properties-in-array-then-sum-up-their-values) – pilchard Jan 25 '23 at 13:13
  • @ChrisG, I just covert the timestamp to date here https://www.epochconverter.com – happy happy Jan 25 '23 at 14:02

2 Answers2

0
function getMonday(d) {
    d = new Date(d);
    let day = d.getDay(),
        diff = d.getDate() - day + (day === 0 ? -6:1); // adjust when day is sunday
    return new Date(d.setDate(diff));
}


let result = [{"Title": "Title_1", "Sum": 0}, {"Title": "Title_2", "Sum": 0}];
let NOW = Math.floor(new Date(getMonday(new Date())).getTime() / 1000);
data.forEach(elm => {
    if (elm.Title === result[0].Title && elm.CreateTs > NOW) {
        result[0].Sum += elm.Positive;
    }
    if (elm.Title === result[1].Title && elm.CreateTs > NOW) {
        result[1].Sum += elm.Positive;
    }
});

Here is a code that will verify the title of your object and check if the timestamp is superiror to the Monday of the week.

fexkoser
  • 13
  • 2
  • Thanks for your answer! Is this method extensible when there are more title but not just Title_1 and Title_2? – happy happy Jan 25 '23 at 14:29
  • No its currently not, but it can be done by a scan of the element and the creation of the needed json object int the result array. And please remeber to tick an answer if its right. – fexkoser Jan 25 '23 at 14:32
-1

First we need to filter to get current week start timestamp and end timestamp and we can filter CreateTs with that

Then we can use reduce to group our objects we use object instead of array because it is easier as you see, then we can use values() to convert obj to arr

const now = new Date();
const currentWeekStart = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getUTCDay());
const currentWeekEnd = new Date(now.getFullYear(), now.getMonth(), now.getDate() + (6 - now.getUTCDay()));

const result = data
    .filter((item) => {
        const date = new Date(item.CreateTs);
        return date >= currentWeekStart && date <= currentWeekEnd;
    })
    .reduce((acc, item) => {
        const { Title, Positive } = item;
        if (!acc[Title]) {
            acc[Title] = { Title, Positive_sum: Positive };
        } else {
            acc[Title].Positive_sum += Positive;
        }
        return acc;
    }, {});

console.log(Object.values(result));