2

javascript group on an array of objects with timestamp range difference

I want to group the messages objects of the array by within a five minutes timestamp range.

  1. src data

let msgs = [
    {
      "msgId": 606896983568064500,
      "text": "B",
      "time": "2019/08/02 17:11",
      "count": 1,
      "isSelf": true
    },
    {
      "msgId": 606897486704189400,
      "text": "A",
      "time": "2019/08/02 17:13",
      "count": 2,
      "isSelf": true
    },
    {
      "msgId": 606892034444533800,
      "text": "C",
      "time": "2019/08/02 16:52",
      "count": 3
    },
    {
      "msgId": 606889698041045000,
      "text": "D",
      "time": "2019/08/02 16:42",
      "count": 3
    },
    {
      "msgId": 606866947376980000,
      "text": "E",
      "time": "2019/08/02 15:12",
      "count": 3
    },
    {
      "msgId": 606866947376970000,
      "text": "G",
      "time": "2019/08/01 5:12",
      "count": 3
    },
    {
      "msgId": 606866947376910000,
      "text": "F",
      "time": "2019/08/01 15:12",
      "count": 3
    },
];

  1. wanted result

timestamp by ASC order

DB groups = {
    "0": [
        {
            "msgId": 606866947376970000,
            "text": "G",
            "time": "2019/08/01 5:12",
            "count": 3
        }
    ],
    "1": [
        {
            "msgId": 606866947376910000,
            "text": "F",
            "time": "2019/08/01 15:12",
            "count": 3
        }
    ],
    "2": [
        {
            "msgId": 606866947376980000,
            "text": "E",
            "time": "2019/08/02 15:12",
            "count": 3
        }
    ],
    "3": [
        {
            "msgId": 606889698041045000,
            "text": "D",
            "time": "2019/08/02 16:42",
            "count": 3
        }
    ],
    "4": [
        {
            "serialNum": "C 1564735983212",
            "msgId": 606892034444533800,
            "text": "C",
            "time": "2019/08/02 16:52",
            "count": 3
        }
    ],
    "5": [
        {
            "msgId": 606896983568064500,
            "text": "B",
            "time": "2019/08/02 17:11",
            "count": 1,
            "isSelf": true
        },
        {
            "msgId": 606897486704189400,
            "text": "A",
            "time": "2019/08/02 17:13",
            "count": 2,
            "isSelf": true
        }
    ],
}

got result


DB groups = {
    "0": [
        {
            "msgId": 606866947376910000,
            "text": "F",
            "time": "2019/08/01 15:12",
            "count": 3
        }
    ],
    "1": [
        {
            "msgId": 606866947376970000,
            "text": "G",
            "time": "2019/08/01 5:12",
            "count": 3
        }
    ],
    "2": [
        {
            "msgId": 606866947376980000,
            "text": "E",
            "time": "2019/08/02 15:12",
            "count": 3
        }
    ],
    "3": [
        {
            "msgId": 606889698041045000,
            "text": "D",
            "time": "2019/08/02 16:42",
            "count": 3
        }
    ],
    "4": [
        {
            "msgId": 606892034444533800,
            "text": "C",
            "time": "2019/08/02 16:52",
            "count": 3
        }
    ],
    "5": [
        {
            "msgId": 606896983568064500,
            "text": "B",
            "time": "2019/08/02 17:11",
            "count": 1,
            "isSelf": true
        },
        {
            "msgId": 606897486704189400,
            "text": "A",
            "time": "2019/08/02 17:13",
            "count": 2,
            "isSelf": true
        }
    ],
    "6": [
        {
            "msgId": 606896983568064500,
            "text": "B",
            "time": "2019/08/02 17:11",
            "count": 1,
            "isSelf": true
        },
        {
            "msgId": 606897486704189400,
            "text": "A",
            "time": "2019/08/02 17:13",
            "count": 2,
            "isSelf": true
        }
    ]
}

  1. my solution with duplicate group bug

enter image description here


let log = console.log;

// asc & ascending
msgs.sort((a, b) => (a.msgId > b.msgId) ? 1 : -1);

log(`msgs =`, JSON.stringify(msgs, null, 4));

// mm, ss, ms
const fiveMinutes = 5 * 60 * 1000;

let DB = {};
let len = msgs.length;

let groupFlag = ``;
if (msgs[0]) {
    groupFlag = Date.parse(msgs[0].time);
}

let cp_msgs = msgs;

let finished = false;

// group flag
for (let i = 0; i < len; i++) {
    // filter
    let new_cp_msgs = cp_msgs.filter(
        (obj, k) => {
            let {
                time,
            } = obj;
            if (time.includes(`/`)) {
                time = Date.parse(time);
            } else {
                let today = autoGetToday(time);
                time = Date.parse(today);
            }
            let min = Math.abs(groupFlag - time);
            if (min <= fiveMinutes) {
                // DB[i].push(obj);
            } else {
                return obj;
            }
        }
    );
    if (cp_msgs.length <= 1 && finished) {
        break;
    } else {
        DB[i] = [];
    }
    log(`cp_msgs =`, cp_msgs);
    for (let j = 0; j < cp_msgs.length; j++) {
        if (cp_msgs.length === 1) {
            finished = true;
        }
        let obj = cp_msgs[j];
        let {
            time,
        } = obj;
        if (time.includes(`/`)) {
            time = Date.parse(time);
        } else {
            let today = autoGetToday(time);
            time = Date.parse(today);
        }
        let min = Math.abs(time - groupFlag);
        if (min <= fiveMinutes) {
            DB[i].push(obj);
        } else {
            groupFlag = time;
            cp_msgs = new_cp_msgs;
            break;
        }
    }
}

const autoGetToday = (time = ``, debug = false) => {
    let log = console.log;
    let date = new Date();
    let year = date.getFullYear();
    let month = date.getMonth() + 1;
    let day = date.getDate();
    if (debug) {
        log(year);
        log(month);
        log(day);
    }
    let today = `${year}/${month}/${day} ${time}`;
    if (debug) {
        log(`today =`, today);
    }
    return today;
};

console.log(`DB groups =`, JSON.stringify(DB, null, 4));




repl

let msgs = [
    {
      "msgId": 606896983568064500,
      "text": "B",
      "time": "2019/08/02 17:11",
      "count": 1,
      "isSelf": true
    },
    {
      "msgId": 606897486704189400,
      "text": "A",
      "time": "2019/08/02 17:13",
      "count": 2,
      "isSelf": true
    },
    {
      "msgId": 606892034444533800,
      "text": "C",
      "time": "2019/08/02 16:52",
      "count": 3
    },
    {
      "msgId": 606889698041045000,
      "text": "D",
      "time": "2019/08/02 16:42",
      "count": 3
    },
    {
      "msgId": 606866947376980000,
      "text": "E",
      "time": "2019/08/02 15:12",
      "count": 3
    },
    {
      "msgId": 606866947376970000,
      "text": "G",
      "time": "2019/08/01 5:12",
      "count": 3
    },
    {
      "msgId": 606866947376910000,
      "text": "F",
      "time": "2019/08/01 15:12",
      "count": 3
    },
];

let log = console.log;

// asc & ascending
msgs.sort((a, b) => (a.msgId > b.msgId) ? 1 : -1);

log(`msgs =`, JSON.stringify(msgs, null, 4));

// mm, ss, ms
const fiveMinutes = 5 * 60 * 1000;

let DB = {};
let len = msgs.length;

let groupFlag = ``;
if (msgs[0]) {
    groupFlag = Date.parse(msgs[0].time);
}

let cp_msgs = msgs;

let finished = false;

// group flag
for (let i = 0; i < len; i++) {
    // filter
    let new_cp_msgs = cp_msgs.filter(
        (obj, k) => {
            let {
                time,
            } = obj;
            if (time.includes(`/`)) {
                time = Date.parse(time);
            } else {
                let today = autoGetToday(time);
                time = Date.parse(today);
            }
            let min = Math.abs(groupFlag - time);
            if (min <= fiveMinutes) {
                // DB[i].push(obj);
            } else {
                return obj;
            }
        }
    );
    if (cp_msgs.length <= 1 && finished) {
        break;
    } else {
        DB[i] = [];
    }
    log(`cp_msgs =`, cp_msgs);
    for (let j = 0; j < cp_msgs.length; j++) {
        if (cp_msgs.length === 1) {
            finished = true;
        }
        let obj = cp_msgs[j];
        let {
            time,
        } = obj;
        if (time.includes(`/`)) {
            time = Date.parse(time);
        } else {
            let today = autoGetToday(time);
            time = Date.parse(today);
        }
        let min = Math.abs(time - groupFlag);
        if (min <= fiveMinutes) {
            DB[i].push(obj);
        } else {
            groupFlag = time;
            cp_msgs = new_cp_msgs;
            break;
        }
    }
}

const autoGetToday = (time = ``, debug = false) => {
    let log = console.log;
    let date = new Date();
    let year = date.getFullYear();
    let month = date.getMonth() + 1;
    let day = date.getDate();
    if (debug) {
        log(year);
        log(month);
        log(day);
    }
    let today = `${year}/${month}/${day} ${time}`;
    if (debug) {
        log(`today =`, today);
    }
    return today;
};

console.log(`DB groups =`, JSON.stringify(DB, null, 4));

  1. right solution(looking for help...)

1

1 Answer 1

4

You could sort the array in advance and get the delta of times for checking.

var data = [{ msgId: 606896983568064500, text: "B", time: "2019/08/02 17:11", count: 1, isSelf: true }, { msgId: 606897486704189400, text: "A", time: "2019/08/02 17:13", count: 2, isSelf: true }, { serialNum: "C 1564735983212", msgId: 606892034444533700, text: "C", time: "2019/08/02 16:52", count: 3 }, { msgId: 606889698041045000, text: "D", time: "2019/08/02 16:42", count: 3 }, { msgId: 606866947376980000, text: "E", time: "2019/08/02 15:12", count: 3 }, { msgId: 606866947376970000, text: "G", time: "2019/08/01 5:12", count: 3 }, { msgId: 606866947376910000, text: "F", time: "2019/08/01 15:12", count: 3 }],
    result = data
        .sort((a, b) => new Date(a.time) - new Date(b.time))
        .reduce((r, o, i, { [i - 1]: last }) => {
            if (!last || new Date(o.time) - new Date(last.time) > 5 * 60 * 1000) {
                r.push([o]);
            } else {
                r[r.length - 1].push(o);
            }
            return r;
        }, []);

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your time! That's Array result is OK, but not the exactly Object result which I wanted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.