Sort object of weekdays like Sunday, Monday, ..., Saturday

20,494

Solution 1

Like I said in my comment, you can't sort an object but if you can change your data's format to have an array, you can easily sort it by using [].sort

let data = [
  { day: "Friday", hours: ["5:00pm to 12:00am"] },
  { day: "Wednesday", hours: ["5:00pm to 11:00pm"] },
  { day: "Sunday", hours: ["11:00am to 11:00pm"] },
  { day: "Thursday", hours: ["5:00pm to 11:00pm"] },
  { day: "Saturday", hours: ["11:00am to 12:00am"] }
];

const sorter = {
  // "sunday": 0, // << if sunday is first day of week
  "monday": 1,
  "tuesday": 2,
  "wednesday": 3,
  "thursday": 4,
  "friday": 5,
  "saturday": 6,
  "sunday": 7
}

data.sort(function sortByDay(a, b) {
  let day1 = a.day.toLowerCase();
  let day2 = b.day.toLowerCase();
  return sorter[day1] - sorter[day2];
});

console.log(data);
document.write("<pre>" + JSON.stringify(data, null, 3) + "</pre>");

edit

To "order" your object's keys by day of the week, again order is not guaranteed, use at your own risk

let data = {
  "Friday": ["5:00pm to 12:00am"],
  "Wednesday": ["5:00pm to 11:00pm"],
  "Sunday": ["11:00am to 11:00pm"],
  "Thursday": ["5:00pm to 11:00pm"],
  "Saturday": ["11:00am to 12:00am"]
};

const sorter = {
  "monday": 1,
  "tuesday": 2,
  "wednesday": 3,
  "thursday": 4,
  "friday": 5,
  "saturday": 6,
  "sunday": 7
};

let tmp = [];
Object.keys(data).forEach(function(key) {
  let value = data[key];
  let index = sorter[key.toLowerCase()];
  tmp[index] = {
    key: key,
    value: value
  };
});

let orderedData = {};
tmp.forEach(function(obj) {
  orderedData[obj.key] = obj.value;
});

console.log(orderedData);
document.write("<pre>" + JSON.stringify(orderedData, null, 3) + "</pre>");

Solution 2

Just as a proof of concept using ES6, this should work Requires MomentJS:

const unordered = {"Friday":["5:00pm to 12:00am"] ,"Wednesday":["5:00pm to 11:00pm"],"Sunday":["11:00am to 11:00pm"], "Thursday":["5:00pm to 11:00pm"],"Saturday":["11:00am to 12:00am"]};

const ordered = {};
Object.keys(unordered).sort(function (a, b) {
    return moment(a, 'ddd dddd').weekday() > moment(b, 'ddd dddd').weekday();
}).forEach(function(key) {
    ordered[key] = unordered[key];
});

console.log(ordered);

This returns:

{ 
    Sunday: [ '11:00am to 11:00pm' ],
    Wednesday: [ '5:00pm to 11:00pm' ],
    Thursday: [ '5:00pm to 11:00pm' ],
    Friday: [ '5:00pm to 12:00am' ],
    Saturday: [ '11:00am to 12:00am' ] 
}

Note: This is mainly a proof of concept to show it is possible, there are issues such as MomentJS treating Sunday as day 0 (based on user locale etc). You could easily write your own mapping of weekdays to int (Monday -> 0, Tuesday -> 1) and remove the MomentJS dependency.

EDIT: Expanding on above:

var days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

Then change the sort function to

return days.indexOf(a) > days.indexOf(b)

const unordered = {"Friday":["5:00pm to 12:00am"] ,"Wednesday":["5:00pm to 11:00pm"],"Sunday":["11:00am to 11:00pm"], "Thursday":["5:00pm to 11:00pm"],"Saturday":["11:00am to 12:00am"]};

var days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

const ordered = {};

Object.keys(unordered).sort(function (a, b) {
    return days.indexOf(a) > days.indexOf(b);
}).forEach(function(key) {
    ordered[key] = unordered[key];
});

console.log(ordered);

Example: http://www.es6fiddle.net/ihqg46kp/

Share:
20,494
Vishal Rajole
Author by

Vishal Rajole

Full Stack Engineer with 7+ yrs of hands on experience on building SPA/PWA on Angular.io/React/Next.js/Node.js stack and mobile apps with React Native. Familiar with CICD/deployment with AWS, Unit testing/integration testing, Payment gateway integrations, OAuth, Analytic tools like Google Analytics/Firebase/Clevertap

Updated on April 30, 2020

Comments

  • Vishal Rajole
    Vishal Rajole about 4 years

    How to sort Javascript object of week days by weekdays i.e Here, is JSON format of object:

     {"Friday":["5:00pm to 12:00am"] ,"Wednesday":["5:00pm to 11:00pm"],"Sunday":["11:00am to 11:00pm"], "Thursday":["5:00pm to 11:00pm"],"Saturday":["11:00am to 12:00am"]}
    

    where key is day i.e."Wednesday". I want to sort it based on order of weekdays i.e Sunday, Monday, Tuesday etc

    Expected Output is:

    { "Wednesday":["5:00pm to 11:00pm"], "Thursday":["5:00pm to 11:00pm"], "Friday":["5:00pm to 12:00am"], "Saturday":["11:00am to 12:00am"], "Sunday":["11:00am to 11:00pm"]}
    

    this is what i was trying.

    var keys = {}; 
    Object.keys(scope.daySpecificHours)
    .map(function (k) { return [k, scope.daySpecificHours[k]]; })
    .sort(function (a, b) {
    if (a[0] < b[0]) return -1;
    if (a[0] > b[0]) return 1;
    return 0;
    })
    .forEach(function (d) {
    scope.daySpecificHours[d[0]] = d;
    });
    

    Thanks.

    • Reinstate Monica Cellio
      Reinstate Monica Cellio over 8 years
      Can you post your code to show us what you've already tried, and explain what's wrong with it?
    • Vishal Rajole
      Vishal Rajole over 8 years
      I tried on console, but not able to complete it.
    • SlashmanX
      SlashmanX over 8 years
      Just to point you in the right direction. Moment.JS let's you provide an object like so and get the resulting day number moment("Friday", "e").weekday(). Combining this with something like lodash's sortBy could work pretty easily. Just a suggestion.
    • Reinstate Monica Cellio
      Reinstate Monica Cellio over 8 years
      @VishalRajole "I tried on console" is not posting your code that you need help with. Stack Overflow != Write my code for me.
    • Vishal Rajole
      Vishal Rajole over 8 years
      Updated my question. Please have a look.
    • Shanoor
      Shanoor over 8 years
      It's an object, you can't sort by properties name, order is not guaranteed in the specification: stackoverflow.com/questions/5525795/…
    • instinct
      instinct over 7 years
      This is not duplicate! If we sort weekdays by considering them a text, then sort order would be wrong. stackoverflow.com/questions/1069666/… doesnot answer this question.
  • Vishal Rajole
    Vishal Rajole over 8 years
    Thanks. but I want to sort based on key names. Do check input object.
  • Vishal Rajole
    Vishal Rajole over 8 years
    Thanks. Tried. It is not working
  • SlashmanX
    SlashmanX over 8 years
    @VishalRajole In what way is it not working?
  • Vishal Rajole
    Vishal Rajole over 8 years
    It is returning same object like unsorted. I didn't got your point to remove moment dependency. Can you elaborate?
  • Shanoor
    Shanoor over 8 years
    I updated my answer but use the code at your own risk.
  • SlashmanX
    SlashmanX over 8 years
    @VishalRajole I've updated the answer to work without MomentJS
  • Vishal Rajole
    Vishal Rajole over 8 years
    Thanks. Yes it is working in fiddle. But same code not working in chrome.
  • SlashmanX
    SlashmanX over 8 years
    @VishalRajole You'll likely need an ES6 library like Babel.
  • intcreator
    intcreator almost 6 years
    According to MDN, the compare function should return a negative number, a positive number, or 0, not true or false.
  • Jobokai
    Jobokai about 5 years
    I've added an edit to update the function to return the values (if (sorter[day1] > sorter[day2]) return 1; if (sorter[day2] > sorter[day1]) return -1; return 0;) so that it will sort correctly.