0

I have array of objects like:

[
    { hour: "08:00" },
    { hour: "08:30" },
    { hour: "09:00" },
    { hour: "09:30" },
    { hour: "10:00" },
]

and list of "priorities":

[
    "09:00",
    "09:30",
    "12:00" // Yes, it doesn't exist in array of available hours
]

I'd like have output of the function:

[
    { hour: "09:00" },
    { hour: "09:30" },
    { hour: "08:00" },
    { hour: "08:30" },
    { hour: "10:00" },
]

I think I could use .sort with own compare function in JavaScript, but I don't have any idea how can I even start with this problem.

I'll be grateful for any tips for solving my problem.

1
  • So check if the value is in the array, if not sort by value Commented Mar 26, 2020 at 21:17

4 Answers 4

1

you can do it with sort in one go ... with a reversed priority list to make it easy ... i.e. the highest priority has the highest indexOf, and anything not in the list has a priority of -1

const data = [
    { hour: "08:00" },
    { hour: "08:30" },
    { hour: "09:00" },
    { hour: "09:30" },
    { hour: "10:00" },
]

const priorities = [
    "09:00",
    "09:30",
    "12:00" // Yes, it doesn't exist in array of available hours
];
const reverse = priorities.slice().reverse();

let result = data.sort((a, b) => {
    prioritya = reverse.indexOf(a.hour);
    priorityb = reverse.indexOf(b.hour);
    if (prioritya === priorityb) {
        return a.hour.localeCompare(b.hour);
    }
    return priorityb - prioritya;
});
console.log(result);

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

2 Comments

slice is for creating new array instead of mutating reverse? Is it ok to use [...priorities].reverse()?
yep, same thing - I always forget about that alternative to slice
1

Check to see if it is in the list, if it is, sort by that, if not sort by the hour.

var data = [
  { hour: "08:00" },
  { hour: "12:00" },
  { hour: "08:30" },
  { hour: "09:00" },
  { hour: "09:30" },
  { hour: "10:00" },  
]

var priorities = [
  "09:00",
  "09:30",
  "12:00" 
]

var sorted = data.sort (function (a,b) {
  var aH = a.hour
  var bH = b.hour
  var aIndex = priorities.indexOf(aH)
  var bIndex = priorities.indexOf(bH)
  /* if both are priorities sort by index */
  if (aIndex > -1 && bIndex > -1) {
    return aIndex === bIndex ? 0 : aIndex > bIndex ? 1 : -1
  } else if (aIndex > -1) { // if a in priority, move up
    return -1
  } else if (bIndex > -1) { // if b in priority, move up
    return 1
  } else { // if not priorities, sort by string
    return aH.localeCompare(bH)
  }
})

console.log(sorted)

Comments

1

Wouldn't a simple sort() like the one below do the job ?

const arr = [{hour:"08:00"},{hour:"08:30"},{hour:"09:00"},{hour:"09:30"},{hour:"10:00"}],
      priority = ["09:00","09:30","12:00"],
      
      sorted = arr.sort(({hour:hourA},{hour:hourB}) =>
        !priority.includes(hourA) ?
        1 :
        !priority.includes(hourB) ?
        -1 :
        priority.indexOf(hourA) - priority.indexOf(hourB)
      )
      
console.log(sorted)
.as-console-wrapper{min-height:100%;}

Comments

0

You could take an object with indices for priorities and take for unknown properties Number.MAX_VALUE.

var data = [{ hour: "08:00" }, { hour: "08:30" }, { hour: "09:00" }, { hour: "09:30" }, { hour: "10:00" }],
    priorities = ["09:00", "09:30", "12:00"],
    order = priorities.reduce((r, hour, i) => (r[hour] = i + 1, r), {});

data.sort(({ hour: a }, { hour: b }) =>
    (order[a] || Number.MAX_VALUE) - (order[b] || Number.MAX_VALUE));

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.