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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.