简体   繁体   中英

create a component which accept the input of time range object and return the array of merged time range object javascript

create a component which accept the input of time range object and return the array of merged time range object

Input

[
  {"day":2, "sTime":"08:00", "eTime":"09:00"},
  {"day":2, "sTime":"09:00", "eTime":"10:00"},
  {"day":2, "sTime":"09:00", "eTime":"10:00"},
  {"day":2, "sTime":"10:00", "eTime":"11:00"},
  {"day":2, "sTime":"10:30", "eTime":"11:30"},
  {"day":2, "sTime":"10:00", "eTime":"12:00"},
  {"day":2, "sTime":"10:00", "eTime":"11:00"}
]

Output

[
  { "sTime":"08:00", "eTime":"09:00", "mergedSession": [] },
  { "sTime":"09:00", "eTime":"10:00", "mergedSession": [
    { "day":2, "sTime":"09:00", "eTime":"10:00" },
    { "day":2, "sTime":"09:00", "eTime":"10:00" }
  ]},
  { "sTime":"10:00", "eTime":"12:00", "mergedSession": [
    { "day":2, "sTime":"10:00", "eTime":"11:00" },
    { "day":2, "sTime":"10:30", "eTime":"11:30" },
    { "day":2, "sTime":"10:00", "eTime":"12:00" },
    { "day":2, "sTime":"10:00", "eTime":"11:00" }
  ]}
]

Here's an attempt that produces your desired result. What it roughly does (comments in the code should explain some more details)

  1. Prepare the data for easier comparison (add Number values for the times)
  2. Go over the data and create sessions
  3. If the start of a slot fits in the current session
    • push it to the inner array
    • extend end of session if needed
  4. If the start is outside the slot, create a new session and continue
  5. Sanitize the output and put it in the correct order

PS Code style is heavily opinionated, let me know if there's stuff that's hard to read... 😅

 // UTILS // Utility to go from time string to comparable int const parseTime = str => Number(str.replace(":", "")); // Translate back to a time strin. Eg: 800 -> "08:00" const timeToStr = int => { const str = (int + "").padStart(4, "0"); return [str[0], str[1], ":", str[2], str[3]].join(""); }; // Logic for checking if a slot is in the previous session const inRange = (min, max, t) => t >= min && t < max; // MERGE LOGIC const merge = ([lastMerge, ...merges], { day, sTime, eTime, sVal, eVal }) => // There has to be a "session", lastMerge && // The session has to match our current day, lastMerge.day === day && // Our start has to be within the range of the session: inRange( lastMerge.sVal, lastMerge.eVal, sVal ) ? [{ day, sVal: lastMerge.sVal, // Extend the session if needed eVal: Math.max(eVal, lastMerge.eVal), sTime: lastMerge.sTime, // Update the original string as well, eTime: timeToStr(Math.max(eVal, lastMerge.eVal)), // Add the current slot to the session mergedSession: [ { day, sTime, eTime, sVal, eVal} ].concat(lastMerge.mergedSession) }].concat(merges) : // Create a new session [{ day, sVal, eVal, sTime, eTime, mergedSession: [ { day, sTime, eTime, sVal, eVal} ] }].concat(lastMerge || []).concat(merges); const input = [ {"day":2, "sTime":"08:00", "eTime":"09:00"}, {"day":2, "sTime":"09:00", "eTime":"10:00"}, {"day":2, "sTime":"09:00", "eTime":"10:00"}, {"day":2, "sTime":"10:00", "eTime":"11:00"}, {"day":2, "sTime":"10:30", "eTime":"11:30"}, {"day":2, "sTime":"10:00", "eTime":"12:00"}, {"day":2, "sTime":"10:00", "eTime":"11:00"} ]; console.log( input // Add some numeric "time" values for easier comparisons .map(slot => Object.assign({}, slot, { sVal: parseTime(slot.sTime), eVal: parseTime(slot.eTime) })) // The actual merge .reduce(merge, []) // We concatenated the results in reverse; undo that .reverse() // Remove the temporary int. values used for easier comparisons .map(({ day, sTime, eTime, mergedSession }) => // Remove mergedSessions with 1 element ({ sTime, eTime, mergedSession: mergedSession.length > 1 ? mergedSession.map(({ day, sTime, eTime }) => ({ day, sTime, eTime })) : [] }) ) ) 

var myArray=[{"day":2,"sTime":"08:00","eTime":"09:00"},{"day":2,"sTime":"09:00","eTime":"10:00"},{"day":2,"sTime":"09:00","eTime":"10:00"},{"day":2,"sTime":"10:00","eTime":"11:00"},{"day":2,"sTime":"10:30","eTime":"11:30"},{"day":2,"sTime":"10:00","eTime":"12:00"},{"day":2,"sTime":"10:00","eTime":"11:00"}];

var newarr=[];
var output=[];
var scipArray=[];

function merge(array){

                if(array.length==0)
                {
                        console.log("Array is empty");
                }else{
                    for (var i = 0; i < array.length; i++) {
                    var a=array[i]["sTime"].split(":");
                    var b=array[i]["eTime"].split(":");
                    var aminutes=(+a[0]) * 60 + (+a[1]);
                    var bminutes = (+b[0]) * 60 + (+b[1]);

                    calculateMerge(array,aminutes,bminutes);

                        if(scipArray.includes(i)==true)
                        {
                            //continue;
                        }else{
                    var mergeArray={"sTime":array[i]["sTime"],"eTime":array[i]["eTime"],"mergeSession":newarr};
                    output=output.push(mergeArray);
                        }

                    }console.log(output);
                }   

}

function calculateMerge(array,aminutes,bminutes){

        for(var j = 0; j < array.length; j++){

            var c=array[j]["sTime"].split(":");
            var d=array[j]["eTime"].split(":");
            var cminutes=(+c[0]) * 60 + (+c[1]);
            var dminutes = (+d[0]) * 60 + (+d[1]);

            if(aminutes<=cminutes && bminutes>=dminutes){
                newarr.push(array[j]);
                scipArray.push(j);
            }
            else{
                newarr;
            }
        }

}

merge(myArray);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM