Home > Mobile >  How to group according to date{ the key in each object is the day - from the first day of the month
How to group according to date{ the key in each object is the day - from the first day of the month

Time:09-23

const a = [
    {
      "record_id": "2ff8212f-5ec9-4453-b1f3-91840a3fb152",
      "status_date_activity": {
        "On Rent": 1663841740869
      }
    },
    {
      "record_id": "c8c11f97-5eda-4f9b-a6a0-5a3f259c85b6",
      "status_date_activity": {
        "On Rent": 1663826452195
      }
    },
    {
      "record_id": "8c23aa44-4113-4feb-92b7-eb265f3e11e2",
      "status_date_activity": {
        "On Rent": 1663837445146,
        "Draft": 1663808712701,
        "Active": 1663808565409
      }
    },
    {
      "record_id": "fd88fbfc-a8d3-4a86-b245-0f8334b4f11f",
      "status_date_activity": {
        "On Rent": 1663841622113
      }
    },
    {
      "record_id": "e0ed3dcf-943c-48d1-b387-87e758e5ed9a",
      "status_date_activity": {
        "On Rent": 1663814717259,
        "Unprepped": 1663841617839
      }
    },
    {
      "record_id": "cef4d093-0ced-4d0d-b9f6-90c2e2687bbe",
      "status_date_activity": {
        "On Rent": 1663892940412
      }
    }
  ]

Given the array above, my goal is to return an array of object that are group according to date(On Rent). But first I need to get the start of the month (for example this month is september, and also the current date of this month so for example Sept 25) so my final output should be like this

const final_result = [
{
"Sept 1": [] // empty array because theres is no on rent on this day
},
{
"Sept 2": []// empty array because theres is no on rent on this day
},
...and so on on,
{
"Sept 22":[{
...the value above that on rent is belong to this date( no matter what time it is)
}]
},
...until it reaches to 
"Sept 25":[]// empty array because theres is no on rent on this day
]

Also I made this code but I need to get the firstDateOfTheMonth and the currentDate

const b = a.reduce((acc,curr)=>{
  const dateN = new Date(curr.status_date_activity?.['On Rent']).toLocaleDateString("en-us", {
    day: "numeric",
    month: "short"
  })
  return {
    ...acc,
    [dateN]:[...(acc[dateN] ?? []),curr]
  }
},{})

CodePudding user response:

Grouping approach

  1. Make an empty object days with key as date like
{
  "Sep 1": {
    "Sep 1": []
  },
  "Sep 2": {
    "Sep 2": []
  },
  1. Merge empty object with an array

  2. Get only values of merged object

Live Demo

const arr = [{"record_id": "2ff8212f-5ec9-4453-b1f3-91840a3fb152","status_date_activity": {"On Rent": 1663841740869}},{"record_id": "c8c11f97-5eda-4f9b-a6a0-5a3f259c85b6","status_date_activity": {"On Rent": 1663826452195}},{"record_id": "8c23aa44-4113-4feb-92b7-eb265f3e11e2","status_date_activity": {"On Rent": 1663837445146,"Draft": 1663808712701,"Active": 1663808565409}},{"record_id": "fd88fbfc-a8d3-4a86-b245-0f8334b4f11f","status_date_activity": {"On Rent": 1663841622113}},{"record_id": "e0ed3dcf-943c-48d1-b387-87e758e5ed9a","status_date_activity": {"On Rent": 1663814717259,"Unprepped": 1663841617839}},{"record_id": "cef4d093-0ced-4d0d-b9f6-90c2e2687bbe","status_date_activity": {"On Rent": 1663892940412}}];

const getRentValue = (item) => item["status_date_activity"]["On Rent"];
const getShortDate = (date) => date.toLocaleDateString("en-US", { month: "short", day: 'numeric' });

const anyDate = new Date(getRentValue(arr.at(0)));
const year = anyDate.getFullYear();
const month = anyDate.getMonth();
const lastMonthDay = new Date(year, month   1, 0).getDate();

const days = Array(lastMonthDay).fill()
  .reduce((acc, _, i) => {
    const shortDate = getShortDate(new Date(year, month, i   1));
    acc[shortDate] = { [shortDate]: [] };
    return acc;
  }, {});

const merged = arr.reduce((acc, item) => {
  const shortDate = getShortDate(new Date(getRentValue(item)));
  acc[shortDate][shortDate].push(item);
  return acc;
}, days);

const result = Object.values(merged);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0 }

CodePudding user response:

Here is one way to do this:

const a = [
    {
      "record_id": "2ff8212f-5ec9-4453-b1f3-91840a3fb152",
      "status_date_activity": {
        "On Rent": 1663841740869
      }
    },
    {
      "record_id": "c8c11f97-5eda-4f9b-a6a0-5a3f259c85b6",
      "status_date_activity": {
        "On Rent": 1663826452195
      }
    },
    {
      "record_id": "8c23aa44-4113-4feb-92b7-eb265f3e11e2",
      "status_date_activity": {
        "On Rent": 1663837445146,
        "Draft": 1663808712701,
        "Active": 1663808565409
      }
    },
    {
      "record_id": "fd88fbfc-a8d3-4a86-b245-0f8334b4f11f",
      "status_date_activity": {
        "On Rent": 1663841622113
      }
    },
    {
      "record_id": "e0ed3dcf-943c-48d1-b387-87e758e5ed9a",
      "status_date_activity": {
        "On Rent": 1663814717259,
        "Unprepped": 1663841617839
      }
    },
    {
      "record_id": "cef4d093-0ced-4d0d-b9f6-90c2e2687bbe",
      "status_date_activity": {
        "On Rent": 1663892940412
      }
    }
  ]

var sep1 = new Date("2022-09-01");
var oneDay = 1000 * 60 * 60 * 24;

var result = {};

for(let i = 0; i < a.length; i  ) {
    let delta = a[i].status_date_activity['On Rent'] - sep1;
    let dayOfMonth = Math.ceil(delta / oneDay);
    if(result[`Sep ${dayOfMonth}`]) {
        result[`Sep ${dayOfMonth}`].push(a[i]);
    } else {
        result[`Sep ${dayOfMonth}`] = [a[i]];
    }
}

console.log(result);

CodePudding user response:

Presented below is one possible way to achieve the desired objective.

Code Snippet

// method to prepopulate an object with empty arrays for dates
// starting from 01 (of current month) till current date
const addEmptyArrays = () => {
  const dt = new Date();    // current date
  const todayUTC = (new Date()).toISOString().split('T')[0];    // UTC yyyy-mm-dd format
  let dtArr = [];           // initial empty array
  let stopAt =  todayUTC.split('-')[2];       // current day as number
  for (let d = 0; d < stopAt; d  ) {          // loop from 1 till current date
    // get start of month in UTC
    let td = new Date(Date.UTC(dt.getUTCFullYear(), dt.getUTCMonth()));
    // add "d" days to start of month
    td.setDate(td.getDate()   d);
    // push to dtArr (only the date-part)
    dtArr.push(td.toISOString().split('T')[0]);
  }
  // use dtArr to make an object with key as each date & value as empty array
  return Object.fromEntries(
    dtArr.map(d => [d, []])
  );
};

const myTransform = arr => (
  arr?.map(
    (ob) => ({
      ...ob,
      rentDate: new Date(
        ob?.["status_date_activity"]?.["On Rent"]
      )?.toISOString()?.split('T')?.[0] ?? 'no-date'
    })
  )?.reduce(
    (acc, {rentDate, ...rest}) => {
      acc[rentDate] ??= [];
      acc[rentDate].push({
        rentDate, ...rest,
      });
      return acc;
    },
    addEmptyArrays()
  )
);

/* explanation
// method to transform array to desired object
const myTransform = arr => ( // arr is the array (being passed as an arg)
  arr?.map(         // iterate arr using ".map()"
    (ob) => ({      // each elt in arr is called "ob" (an object)
      ...ob,        // output consists of all props in ob
      rentDate: new Date(           // and an additional "rentDate" prop
        ob?.["status_date_activity"]?.["On Rent"]
      )?.toISOString()?.split('T')?.[0] ?? 'no-date'
    })              // the timestamp (in milliseconds) is converted to UTC
                    // (using ".toISOString()") and only the date is extracted
                    // (using ".split('T')?.[0])
  )?.reduce(        // the above result of ".map()" is iterated using ".reduce()"
    (acc, {rentDate, ...rest}) => {
      // "acc" is the accumulator, "rentDate" is destructed for direct access
      acc[rentDate] ??= []; // setting acc's prop with key rentDate as empty array initially
      acc[rentDate].push({      // push the rentDate & other props to the array
        rentDate, ...rest,      // NOTE: remove "rentDate" and the original object will
                                // will alone be present in the output
      });
      return acc;   // always return acc
    },
    addEmptyArrays  // initially setting "acc" to object with empty arrays
  )                 // implicit return of ".reduce()"'s return
);
*/

const myArr = [{
    "record_id": "2ff8212f-5ec9-4453-b1f3-91840a3fb152",
    "status_date_activity": {
      "On Rent": 1663841740869
    }
  },
  {
    "record_id": "c8c11f97-5eda-4f9b-a6a0-5a3f259c85b6",
    "status_date_activity": {
      "On Rent": 1663826452195
    }
  },
  {
    "record_id": "8c23aa44-4113-4feb-92b7-eb265f3e11e2",
    "status_date_activity": {
      "On Rent": 1663837445146,
      "Draft": 1663808712701,
      "Active": 1663808565409
    }
  },
  {
    "record_id": "fd88fbfc-a8d3-4a86-b245-0f8334b4f11f",
    "status_date_activity": {
      "On Rent": 1663841622113
    }
  },
  {
    "record_id": "e0ed3dcf-943c-48d1-b387-87e758e5ed9a",
    "status_date_activity": {
      "On Rent": 1663814717259,
      "Unprepped": 1663841617839
    }
  },
  {
    "record_id": "cef4d093-0ced-4d0d-b9f6-90c2e2687bbe",
    "status_date_activity": {
      "On Rent": 1663892940412
    }
  }
];

console.log('transformed array to object with desired format:\n', myTransform(myArr));
.as-console-wrapper { max-height: 100% !important; top: 0 }

Explanation

Inline comments added to the snippet above.

  • Related