Skip to content

JS how to group hh:mm – hours arrays without minutes

How can we group hour arrays according to hours.

var hours = ["22:37", "22:52", "23:07", "23:22", "23:37", "23:52", "0:07", "0:22", "0:37", "0:52", "1:07", "1:22", "1:37", "1:52", "2:07", "2:22", "3:07", "3:22", "4:07", "4:22", "4:37", "4:52", "5:07", "5:22", "6:07", "6:22",  "7:07", "7:22", "7:37", "7:52", "8:07", "8:22", "8:37", "8:52", "9:07", "9:22", "9:37", "9:52", "10:07", "10:22", "10:37", "10:52", "11:07", "11:22", "11:37", "11:52", "12:07", "12:22", "14:07", "14:52", "15:07", "15:22", "16:07", "16:22", "16:37", "16:52", "17:07",  "17:52", "18:07", "18:22", "18:37", "18:52", "19:07", "19:22", "19:37", "19:52", "20:07", "20:22", "20:37", "20:52", "21:07", "21:22", "21:37", "21:52", "22:07", "22:22", "22:37", "22:52", "23:07", "23:22"]

As you see, an hour has multiple minute, like 22:37, 22:52.
I want to create new array like

22: ["22:37", "22:52"],
23: [ "23:07", "23:22", "23:37", "23:52"],
0 : ["0:07", "0:22", "0:37", "0:52"], // next day
... 
20: ["20:07", "20:22", "20:37", "20:52"],// next day
21: ["21:07", "21:22", "21:37", "21:52"],// next day
22: ["22:22", "22:37", "22:52"],
23: ["23:07", "23:22"]

It contains two days hours.

I tried like this

var groupHours = hours.reduce((r, v, i, a) => {
    v = v.split(':')[0] // getting only hours 
    if (v === a[i - 1]) {
        r[r.length - 1].push(v);
    } else {
        r.push(v === a[i + 1] ? [v] : v);
    }
    return r;
}, []);

console.log(groupHours)

But it gives me this result

enter image description here

Answer

var hours = ["22:37", "22:52", "23:07", "23:22", "23:37", "23:52", "0:07", "0:22", "0:37", "0:52", "1:07", "1:22", "1:37", "1:52", "2:07", "2:22", "3:07", "3:22", "4:07", "4:22", "4:37", "4:52", "5:07", "5:22", "6:07", "6:22",  "7:07", "7:22", "7:37", "7:52", "8:07", "8:22", "8:37", "8:52", "9:07", "9:22", "9:37", "9:52", "10:07", "10:22", "10:37", "10:52", "11:07", "11:22", "11:37", "11:52", "12:07", "12:22", "14:07", "14:52", "15:07", "15:22", "16:07", "16:22", "16:37", "16:52", "17:07",  "17:52", "18:07", "18:22", "18:37", "18:52", "19:07", "19:22", "19:37", "19:52", "20:07", "20:22", "20:37", "20:52", "21:07", "21:22", "21:37", "21:52", "22:07", "22:22", "22:37", "22:52", "23:07", "23:22"]

var h = {};

for (var hh of hours) {
    try { 
        h[hh.split(':')[0]].push(hh);    
    }
    catch (e) {
        h[hh.split(':')[0]] = [hh];
    }
}

console.log(h);

Update

Solution for several days:

var hours = ["22:37", "22:52", "23:07", "23:22", "23:37", "23:52", "0:07", "0:22", "0:37", "0:52", "1:07", "1:22", "1:37", "1:52", "2:07", "2:22", "3:07", "3:22", "4:07", "4:22", "4:37", "4:52", "5:07", "5:22", "6:07", "6:22",  "7:07", "7:22", "7:37", "7:52", "8:07", "8:22", "8:37", "8:52", "9:07", "9:22", "9:37", "9:52", "10:07", "10:22", "10:37", "10:52", "11:07", "11:22", "11:37", "11:52", "12:07", "12:22", "14:07", "14:52", "15:07", "15:22", "16:07", "16:22", "16:37", "16:52", "17:07",  "17:52", "18:07", "18:22", "18:37", "18:52", "19:07", "19:22", "19:37", "19:52", "20:07", "20:22", "20:37", "20:52", "21:07", "21:22", "21:37", "21:52", "22:07", "22:22", "22:37", "22:52", "23:07", "23:22"]


function split_by_days(hours) {
    var s = hours.join('#');
    s.match(/[1-9]:d+#0/g).forEach(t=>s=s.split(t).join(t.replace('#','n')));
    return s.split('n').map(x => x.split('#'));
}

function day_to_obj(day) {
    var obj = {};
    for (var hours of day) {
        try { obj[hours.split(':')[0]].push(hours) }
        catch (e) { obj[hours.split(':')[0]] = [hours] }
    }
    return obj;
}

var days = split_by_days(hours);

var array_of_days_objects = days.map(d => day_to_obj(d));

console.log(array_of_days_objects);