Sort Array first by including ID in other Array, second by date

Viewed 29
const linkedProjects = ["2", "3"];
const projects = [
  {
    id: 1,
    name: "Project 1",
    lastUpdate: 1575976301091
  },
  {
    id: 2,
    name: "Project 2",
    lastUpdate: 1575975812091
  },
  {
    id: 3,
    name: "Project 3",
    lastUpdate: 1575976378391
  },
  {
    id: 4,
    name: "Project 4",
    lastUpdate: 15753276301091
  }
];

What I want to achieve:

I want to sort my Array projects which has multiple objects.

First it should order objects first which are included in linkedProjects by ID.

Second it should order the remaining objects by lastUpdate.

What I have done so far:

projects.sort((a, b) => {
    const [dateA, dateB] = [
        a.lastUpdate && a.lastUpdate.getTime(),
        b.lastUpdate && b.lastUpdate.getTime()
    ];
    if (linkedProjects && linkedProjects.length > 0) {
      if (linkedProjects.includes(a.id)) {
        return -1;
      } else {
        return 1;
      }
    }
    if (dateA === dateB) {
        console.log("0a")
        return 0;
    }
    if (!dateA) {
      console.log("1b")
        return 1;
    }
    if (!dateB) {
        console.log("-1b")
        return -1;
    }
    if (dateA > dateB) {
        console.log("-1d")
        return -1;
    }
    if (dateA < dateB) {
        console.log("1")
        return 1;
    }
    return 0;
})

Sorting by lastUpdate works and was implemented before, but my new implementation with linkedProjects does not work.

Outcome should be:

[
  {
    id: 2, // included in linkedProjects
    name: "Project 2",
    lastUpdate: 1575975812091
  },
  {
    id: 3, // included in linkedProjects
    name: "Project 3",
    lastUpdate: 1575976378391
  },
  {
    id: 4,
    name: "Project 4",
    lastUpdate: 15753276301091 // is newer than Project 1
  },
  {
    id: 1,
    name: "Project 1",
    lastUpdate: 1575976301091 // is older than Project 4
  }
]
2 Answers

You could take a function which returns either the order of the projects or a large number and sort by this delta or tyke the delta of the last update.

const
    linkedProjects = [2, 3],
    getOrder = ({ id }) => (linkedProjects.indexOf(id) + 1) || Number.MAX_VALUE,
    projects = [{ id: 1, name: "Project 1", lastUpdate: 1575976301091 }, { id: 2, name: "Project 2", lastUpdate: 1575975812091 }, { id: 3, name: "Project 3", lastUpdate: 1575976378391 }, { id: 4, name: "Project 4", lastUpdate: 15753276301091 }];

projects.sort((a, b) => getOrder(a) - getOrder(b) || b.lastUpdate - a.lastUpdate);

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

This will put first the linked, then sort the remind by lastUpdate

const linkedProjects = ["2", "3"];
const projects = [{id: 1,name: "Project 1",lastUpdate: 1575976301091},{id: 2,name: "Project 2",lastUpdate: 1575975812091},{id: 3,name: "Project 3",lastUpdate: 1575976378391},{id: 4,name: "Project 4",lastUpdate: 15753276301091}];

const sorted = projects.sort(function(a,b){
  if(linkedProjects.indexOf(''+a.id) !== -1) return -1;
  if(linkedProjects.indexOf(''+b.id) !== -1) return 1;
  return b.lastUpdate - a.lastUpdate
});
console.log(sorted);

Related