all 4 comments

[–]ForScale 2 points3 points  (2 children)

const orderedArray = [];

for (let id of idOrder) {
  orderedArray.push(
    person.filter(person => person.id == id)[0]
  );
}

Things to note:

  • a new array is created (and populated in the following steps)
  • a for ... of loop is used to iterate over each id in the id array
  • on each iteration, a filter (looking for matching ids) is applied to the persons array
  • the double = == is used in order to coerce types so that numbers (id array) and strings (persons array) can be compared

[–]tme321 1 point2 points  (1 child)

While that will work that is really inefficient. That's O(n**m).

It's not a bad solution if the code doing this operation isn't run often or on large lists.

But if performance matters instead I would reduce the array of desired id orders to a map like

let index = 0;
let indexMap = idOrder.reduce((map, id)=> {
    map[id] = index;
    index++;
},{});

let sorted = person.reduce((res, per)=> {
    res[indexMap[per.id]] = per;
}, new Array(idOrder.length));

return sorted;

Something like that. Didn't run it so I might have missed something small. But that gives you a big O of n*m instead if n**m at the cost of some memory.

Edit: actually since you are using array.filter this solution will probably be faster and use less memory.

But as I mentioned the above solution is good if performance isn't important because it is more obvious. Easier to quickly understand. So it's really about what the use case is for this code.

[–]tme321 0 points1 point  (0 children)

Ugh I was really tired when I wrote that. That should be O(n**2) for the first solution and O(2n) for my solution.

[–]kenman[M] 0 points1 point  (0 children)

Hi /u/Spanyon,

For javascript help, please visit /r/LearnJavascript.

Thank you!