Home > Mobile >  How to group by time-range without taking care of day/month/year in javascript
How to group by time-range without taking care of day/month/year in javascript

Time:10-19

Hi!

I need to create from a list of inputs with timestamps(data) an array of objs showing the scores related to their time range (result) without taking care of day/month/year.

I think to do it i need first to create an array of sub arrays of objs organized by time-range then map all (groupByTimeRange) and i don't have any clue of how to do it.

Time Range:

  • 8h includes 6h to 9h29
  • 11h includes 9h30 to 12h29
  • 14h includes 12h30 to 15h29
  • 17h includes 15h30 to 18h29
  • 20h includes 18h30 to 23h59

Data

 const data = 
   [
    {id: 3337, score: 75, date: '2000-02-02T07:25:00.000Z'},
    {id: 3336, score: 30, date: '2012-06-02T08:24:00.000Z'},
    {id: 3335, score: 25, date: '2020-08-02T09:23:00.000Z'},
    {id: 2234, score: 85, date: '2018-08-02T12:20:00.000Z'},
    {id: 1534, score: 85, date: '2016-08-02T10:30:00.000Z'},
    {id: 3884, score: 85, date: '2019-08-02T11:18:00.000Z'},
    {id: 6534, score: 25, date: '2012-08-02T13:01:00.000Z'},
    {id: 3484, score: 14, date: '2022-08-02T15:22:00.000Z'},
    {id: 2224, score: 87, date: '2021-08-02T14:17:00.000Z'},
    {id: 2234, score: 59, date: '2018-08-02T17:20:00.000Z'},
    {id: 1534, score: 48, date: '2016-08-02T18:24:00.000Z'},
    {id: 3884, score: 25, date: '2019-08-02T16:18:00.000Z'},
    {id: 3287, score: 21, date: '2000-02-02T19:25:00.000Z'},
    {id: 3496, score: 05, date: '2012-06-02T20:24:00.000Z'},
    {id: 9635, score: 67, date: '2020-08-02T22:23:00.000Z'}
   ],

Grouping by time range 8h/11h/14h/17h/20h

These part i don't know how to do it.

const groupByTimeRange = 
 [
   // Group Time range: 8h
   [
    {id: 3337, score: 75, date: '2000-02-02T07:25:00.000Z'},
    {id: 3336, score: 30, date: '2012-06-02T08:24:00.000Z'},
    {id: 3335, score: 25, date: '2020-08-02T09:23:00.000Z'}
   ],
   // Group Time range: 11h 
   [
    {id: 2234, score: 85, date: '2018-08-02T12:20:00.000Z'},
    {id: 1534, score: 85, date: '2016-08-02T10:30:00.000Z'},
    {id: 3884, score: 85, date: '2019-08-02T11:18:00.000Z'}
   ],
   // Group Time range: 14h 
   [
    {id: 6534, score: 25, date: '2012-08-02T13:01:00.000Z'},
    {id: 3484, score: 14, date: '2022-08-02T15:22:00.000Z'},
    {id: 2224, score: 87, date: '2021-08-02T14:17:00.000Z'}
   ],
   // Group Time range: 17h 
   [
    {id: 2234, score: 59, date: '2018-08-02T17:20:00.000Z'},
    {id: 1534, score: 48, date: '2016-08-02T18:24:00.000Z'},
    {id: 3884, score: 25, date: '2019-08-02T16:18:00.000Z'}
   ],
   // Group Time range: 20h 
   [
    {id: 3287, score: 21, date: '2000-02-02T19:25:00.000Z'},
    {id: 3496, score: 05, date: '2012-06-02T20:24:00.000Z'},
    {id: 9635, score: 67, date: '2020-08-02T22:23:00.000Z'}
   ],
  ]

Expected output

const result = 
  [
    {timeRange:"8h", AverageScore: 43%},
    {timeRange:"11h", AverageScore: 85%},
    {timeRange:"14h", AverageScore: 42%},
    {timeRange:"17h", AverageScore: 44%},
    {timeRange:"20h", AverageScore: 31%}
  ]

Thanks a lot taking time helping me.

If something is not clear let me know in comments and i will change it

CodePudding user response:

A simple solution would be to store ranges in an array of triples name - min - max:

const ranges = [
    ['8h', '06:00', '09:29'],
    ['11h', '09:30', '12:29'],
    ['14h', '12:30', '15:29'],
    ['17h', '15:30', '18:29'],
    ['20h', '18:30', '23:59'],
]

and iterate over ranges of find out where the date belongs:

function getRange(date) {
    let hm = date.slice(11, 16)
    for (let [name, min, max] of ranges) {
        if (min <= hm && hm <= max)
            return name;
    }
}

Once this works, loop over the main array and populate the grouping map:

let groups = new Map()

for (let d of data) {
    let rng = getRange(d.date)
    if (!groups.has(rng))
        groups.set(rng, [])
    groups.get(rng).push(d)
}

The .values() of this map will be your groupByTimeRange array.

CodePudding user response:

Here is my version

const ranges = [
{name:"0h", start: "00:00", end: "06:29" },
{name:"8h", start: "06:00", end: "09:29" },
{name:"11h", start: "09:30", end: "12:29" },
{name:"14h", start: "12:30", end: "15:29" },
{name:"17h", start: "15:30", end: "18:29" },
{name:"20h", start: "18:30", end: "23:29" }
];

const groupByTimeRange = data.reduce((acc,cur) => {
  const time = cur.date.split("T")[1].slice(0,-8)
  const range = ranges.find(range => time >= range.start && time <= range.end);
  const name = range.name;
  (acc[name] = acc[name] || []).push(cur);
  return acc;
},{})

console.log(groupByTimeRange)

const results = Object.entries(groupByTimeRange).map(([key,val]) => {
  const sum =  val.reduce((a,b) => { return a b.score },0);
  const avg = Math.round(sum/val.length);
  return  {"timeRange": key, "AverageScore": `${avg}%` };
});

console.log(results);
<script>
const data =    [
    {id: 3337, score: 75, date: '2000-02-02T07:25:00.000Z'},
    {id: 3336, score: 30, date: '2012-06-02T08:24:00.000Z'},
    {id: 3335, score: 25, date: '2020-08-02T09:23:00.000Z'},
    {id: 2234, score: 85, date: '2018-08-02T12:20:00.000Z'},
    {id: 1534, score: 85, date: '2016-08-02T10:30:00.000Z'},
    {id: 3884, score: 85, date: '2019-08-02T11:18:00.000Z'},
    {id: 6534, score: 25, date: '2012-08-02T13:01:00.000Z'},
    {id: 3484, score: 14, date: '2022-08-02T15:22:00.000Z'},
    {id: 2224, score: 87, date: '2021-08-02T14:17:00.000Z'},
    {id: 2234, score: 59, date: '2018-08-02T17:20:00.000Z'},
    {id: 1534, score: 48, date: '2016-08-02T18:24:00.000Z'},
    {id: 3884, score: 25, date: '2019-08-02T16:18:00.000Z'},
    {id: 3287, score: 21, date: '2000-02-02T19:25:00.000Z'},
    {id: 3496, score: 05, date: '2012-06-02T20:24:00.000Z'},
    {id: 9635, score: 67, date: '2020-08-02T22:23:00.000Z'}
   ]
</script>

  • Related