0

I have 2 arrays:

var one = ['da22', 'ye66', '17hy'] and

var two = [{publicID: 'da22', score: '2'}, {publicID: '17hy', score: '2'}, {publicID: 'ye66', score: '2'}]

I want two to be ordered by publicID according to one so it should be

two = [{publicID: 'da22', score: '2'}, {publicID: 'ye66', score: '2'}, {publicID: '17hy', score: '2'}]

Is there a built in method in NodeJS to do this?

I've got it working however its not very efficient. I have a method than can move an element from one index to another moveFromTo(oldIndex, newIndex which I'm using with:

for (var r=0; r<one.length; r++) {
              if (one[r] != two[r]['publicID']) {
                two.moveFromTo(one.indexOf(two[r]['publicID']), r)
                r=-1; continue;
              }
}

But having to use that r=-1 as things move - although works - doesn't seem like the best of ideas.

Any ideas would be appreciated.

Many Thanks.

userMod2
  • 8,312
  • 13
  • 63
  • 115

2 Answers2

1

You can do this with sort() and indexOf()

var one = ['da22', 'ye66', '17hy'];
var two = [{publicID: 'da22', score: '2'}, {publicID: '17hy', score: '2'}, {publicID: 'ye66', score: '2'}];

var result = two.sort(function(a, b) {
  return one.indexOf(a.publicID) - one.indexOf(b.publicID);
})

console.log(result)

You can also create object from one and sort by that object.

var one = ['da22', 'ye66', '17hy'];
var two = [{publicID: 'da22', score: '2'}, {publicID: '17hy', score: '2'}, {publicID: 'ye66', score: '2'}];

var o = one.reduce((r, e, i) => {return r[e]=i, r}, {});

var result = two.sort(function(a, b) {
  return o[a.publicID] - o[b.publicID];
})

console.log(result)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
  • Assigning to `result` is not needed. [`.sort()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) sorts the array *in place*. In addition, it returns the array. However, assigning it to `result` is equivalent to `two.sort(function ...); var result=two;`. – Makyen Sep 01 '16 at 20:56
  • Side note.. If you're looking for speed, Array.sort() is not your best option by a considerable margin. See http://stackoverflow.com/questions/38732480/native-javascript-sort-performing-slower-than-implemented-mergesort-and-quicksor – Patrick Motard Sep 01 '16 at 20:58
  • @PatrickMotard - The maximum number of items in the array would be 100 - I'm assuming that would be fine? – userMod2 Sep 01 '16 at 21:07
  • 1
    If the set is that small then there's likely no reason to over complicate for the sake of performance. Best to choose whatever is most readable no? – Patrick Motard Sep 01 '16 at 21:09
  • Agreed - @Nenad - that first option works a treat! Thanks – userMod2 Sep 01 '16 at 21:11
  • @NenadVracar - quick question how does that `a` and `b` parameters correlate in the sort function? i.e. whats it'd doing exactly? – userMod2 Sep 01 '16 at 21:13
  • 1
    You can check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort and https://en.wikipedia.org/wiki/Sorting_algorithm – Nenad Vracar Sep 01 '16 at 21:17
0

I believe there is a simpler solution. You need to synchronize the order of elements in two arrays by different properties of elements of these arrays, while the first (target) array preserves its order.

To do that, you can reduce the two, and for every current element the reduce function is applied to, put corresponding element of two at certain position in resulting array (aka total):

const one = ['da22', 'ye66', '17hy'];
const two = [{
  publicID: 'da22',
  score: '2'
}, {
  publicID: 'ye66',
  score: '2'
}, {
  publicID: '17hy',
  score: '2'
}];

const sortedTwo = two.reduce((total, current) => {
  total[one.indexOf(current.publicID)] = current; // <- some crazy stuff here

  return total;
}, []);

Make sure publicID property values in two and the values of one are perfectly identical sets.

Speed and immutability of the original array included.

rishat
  • 8,206
  • 4
  • 44
  • 69