Search code examples
javascriptarrayssplice

splice objects from array and move those elements to a different element within array without mutating original


This code does kinda what I need but it mutates the original array and that is not what I want. I know this happens because I'm using splice and push. This object has every day of the week as key and each key has the opening and closing time of the store.

Everything is normal until the friday key which has only the open time object and the close one is on the saturday key(because the store closes the next day), same thing happens for saturday and sunday. What I do is move each object to its corresponding day key but I want to achieve this without mutating the original object.

What am I missing to achieve that?

const days = {
  "monday": [{
      "day": "monday",
      "type": "open",
      "value": 43200
    },
    {
      "day": "monday",
      "type": "close",
      "value": 75600
    }
  ],
  "tuesday": [{
      "day": "tuesday",
      "type": "open",
      "value": 43200
    },
    {
      "day": "tuesday",
      "type": "close",
      "value": 75600
    }
  ],
  "wednesday": [{
      "day": "wednesday",
      "type": "open",
      "value": 43200
    },
    {
      "day": "wednesday",
      "type": "close",
      "value": 75600
    }
  ],
  "thursday": [{
      "day": "thursday",
      "type": "open",
      "value": 43200
    },
    {
      "day": "thursday",
      "type": "close",
      "value": 75600
    }
  ],
  "friday": [{
    "day": "friday",
    "type": "open",
    "value": 36000
  }],
  "saturday": [{
      "day": "friday",
      "type": "close",
      "value": 3600
    },
    {
      "day": "saturday",
      "type": "open",
      "value": 36000
    }
  ],
  "sunday": [{
      "day": "saturday",
      "type": "close",
      "value": 3600
    },
    {
      "day": "sunday",
      "type": "open",
      "value": 43200
    },
    {
      "day": "sunday",
      "type": "close",
      "value": 75600
    }
  ]
}

const result = Object.entries(days).map(([k, v], i) => {
  if (k == "friday") {
    days[k].push(days.saturday.splice(0, 1));
    //console.log(days[k])
  } else if (k == "saturday") {
    days[k].push(days.sunday.splice(0, 1));
    //console.log(days[k])
  }
  return {
    [k]: v
  }
})

console.log(result)


Solution

  • You could take all of the inner objects and use their day properties to rebuild the overall object from scratch:

    const days = {"monday": [{"day": "monday","type": "open","value": 43200},{"day": "monday","type": "close","value": 75600}],"tuesday": [{"day": "tuesday","type": "open","value": 43200},{"day": "tuesday","type": "close","value": 75600}],"wednesday": [{"day": "wednesday","type": "open","value": 43200},{"day": "wednesday","type": "close","value": 75600}],"thursday": [{"day": "thursday","type": "open","value": 43200},{"day": "thursday","type": "close","value": 75600}],"friday": [{"day": "friday","type": "open","value": 36000}],"saturday": [{"day": "friday","type": "close","value": 3600},{"day": "saturday","type": "open","value": 36000}],"sunday": [{"day": "saturday","type": "close","value": 3600},{"day": "sunday","type": "open","value": 43200},{"day": "sunday","type": "close","value": 75600}]};
    
    const result = Object.values(days).flat().reduce((acc, o) => {
        (acc[o.day] ??= []).push(o);
        return acc;
    }, {});
    
    console.log(result);