Home > Net >  How can I group by multiple condition in javascript?
How can I group by multiple condition in javascript?

Time:01-25

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.

CodePudding user response:

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.

CodePudding user response:

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));

  • Related