How to properly format this object to not have duplicate data inside it?

92 Views Asked by At

I have an HTML form where the user can add time data ( start and end ) to the form and can select multiple days to save it. ( this is for a circular pump daily on off time for every day ).

The form looks like this from the user point of view

This is how i process the form:

function saveCircularPumpTimes(){
    $("#circularTableForm").on("submit",function(e){
        e.preventDefault();
        var inputs = $("#circularTableForm").serializeArray();
        console.log(inputs);
        /*
        var newCircularObj = {
                "mon":[
                    { start:"", end:"" },
                    { start:"", end:"" }
                ],
                "tue":[
                    { start:"", end:"" },
                    { start:"", end:"" }
                ],

        };
        */
        var days = $("#circularPumpDays").val();
        var datas = [];
        for(var i = 0; i < inputs.length; i++){ 
        // get all the time data to an array for easier processing later.
            if( inputs[i].name.includes("circularPumpOnTimeStart") ){
                datas.push( { start:"", end:"" } );
                datas[datas.length-1].start = inputs[i].value;
            }else if( inputs[i].name.includes("circularPumpOnTimeEnd") ){
                datas[datas.length-1].end = inputs[i].value;
            }
        }
        console.log("Days: ",days);
        console.log("Datas: ",datas);
    });
}

The days array looks like this:

["mon", "tue", "wed"]

And the datas looks like this:

[
   {start: "15:36", end: "16:36"},
   {start: "15:36", end: "15:36"},
   {start: "15:36", end: "15:37"},
   {start: "15:36", end: "15:37"}
]

When the user select multiple days i would go for it like this:

       for(var i = 0; i < days.length; i++){
            if(Object.prototype.hasOwnProperty.call(newCircularObj, days[i])) {
                // User already have saved data for this day
                if( prompt("This day already exist with data inside it. Would you like to overwrite?") ){
                    newCircularObj[days[i]] = [];
                    for(var k = 0; k < datas.length; k++){
                        newCircularObj[days[i]].push( datas[i] );
                    }
                }
            }else{
                // We don't have saved data for this day, create new
                newCircularObj = new Object(days[i]);
                for(var k = 0; k < datas.length; k++){          // yeah this loop is duplicate. :( i will put it into a function
                    newCircularObj[days[i]].push( datas[i] );
                }
            }
        }

The problem with that approach is the data will be exist multiple times inside the object and i have to save it to an MCU so the space is pretty significant. For example if the user selects all seven days for the same times every time data will be included seven times inside the object.

On the MCU side i'm using ArduinoJSON library with ESP32 and i would process it like this (as you can see the whole stringified json object is inside the ram all the time so i really need the space) :

static const inline void processData(String DATA){ // in every single minute we have to do this and search for the start time.
    boolean found = false;
    SpiRamJsonDocument doc(15000);
    DeserializationError error = deserializeJson(doc, DATA); // we get the data as a JSON string.
    if (error) {
        String Error = "JSON Error Pump ~ ";
        Error += String(error.c_str());
        errorLog(Error);
        Send_Async("No Memory for circular Pump DATA", ";RoomHeating");
    }else {
        JsonObject documentRoot = doc.as<JsonObject>();
        for (JsonPair timeData : documentRoot) {
            if(Time.Get_Day() == timeData.key().c_str()){ // Time.Get_Day() is equalent with the current day String like "mon" or "tue"
                // if the day is okay we have to search for the times
                JsonArray Day = doc[Time.Get_Day()];
                for(int i = 0; i < Day.size(); i++){
                    if(Time_Has_Reached(Day[i]["start"],Day[i]["end"])){ // function for check if the start time has passed but the end is not
                        // if in between
                        found = true;
                        break;
                    }
                }
                if(found){break;}
            }
        }
    }

    if(found){
        // Turn on the pump
    }else{
        // Turn off the pump
    }
}

So the question is, how can i arrange the object so the time data exist only once if it is already saved to a day to be more efficient.

Edit: Example from the final object:

var newCircularObj = {
                "mon":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "tue":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "wed":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "thu":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "sat":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],

};
1

There are 1 best solutions below

5
On

ok this program removes duplicates from newCircularObj:

i have taken your sample and modified some values of newCircularObj:

$(function() {

  function removeDup(ar) {
    return ar.reduce(function(item, e1) {
      var matches = item.filter(function(e2) {
        return e1.start == e2.start && e1.end == e2.end
      });
      if (matches.length == 0) {
        item.push(e1);
      }
      return item;
    }, []);

  }


  var result = {datas:{} };
  Object.keys(newCircularObj).forEach(function(it, i) { 
        result.datas[it] =  removeDup(newCircularObj[it]);
    });


  console.log(result);


});

var newCircularObj = {
                "mon":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:11", end:"15:10" },
                    { start:"14:10", end:"15:11" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "tue":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:11" },
                    { start:"14:11", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "wed":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "thu":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "sat":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],

};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


RESULT

{
  datas: {
    mon: [
    {  end: "15:10",  start: "14:10"},
    {  end: "15:10",  start: "14:11"},
    {  end: "15:11",  start: "14:10"}
    ],
    sat: [
    {  end: "15:10",  start: "14:10"}
    ],
    thu: [
    {  end: "15:10",  start: "14:10"}
    ],
    tue: [
    {  end: "15:10",  start: "14:10"},
    {  end: "15:11",  start: "14:10"},
    {  end: "15:10",  start: "14:11"}
    ],
    wed: [
    {  end: "15:10",  start: "14:10"}
    ]
  }
}