2

Tried to figure it out. Can't. I have 2 arrays, and I would like to sort the index of just one of them to match the index by its object.

Array 1 is as goes:

var arr1 = [
  {
   "name": "bobby",
   "occupation": "singer"
  },
  {
   "name": "mindy",
   "occupation": "artist"
  }
] 

and Array 2:

var arr2 = [
  {
   "name": "mindy",
   "hobby": "drawing"
  },
  {
   "name": "bobby",
   "hobby": "driving"
  }
]

It doesn't really matter which one gets re-indexed. The point is I have two names bobby and mindy and I would like to re-arrange one of these arrays so that their index matches the other.

Jason Chen
  • 2,487
  • 5
  • 25
  • 44
  • didn't include any because i don't think the logic is sound. i tried making a new array and pushing by index. something like `for (let xo = 0; xo < daborder.length; xo++){newarr.push(arr2[arr2.indexOf(arr1.name)]);}` – Jason Chen Jun 24 '18 at 02:27
  • Are the names always going to be in both arrays? – vol7ron Jun 24 '18 at 03:17

2 Answers2

5

Use sort with compareFunction.

Find the comments inline below.

var arr1 = [
  {
   "name": "bobby",
   "occupation": "singer"
  },
  {
   "name": "mindy",
   "occupation": "artist"
  }
] 

var arr2 = [
  {
   "name": "mindy",
   "hobby": "drawing"
  },
  {
   "name": "bobby",
   "hobby": "driving"
  }
]

// create intermediate array of arr2 names
arr2Names = arr2.map(x => x.name)

// use sort:
arr1 = arr1.sort((x,y) => arr2Names.indexOf(x.name) - arr2Names.indexOf(y.name))
console.log(arr1, arr2)

var arr2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
var arr1 = ['b', 'd', 'g', 'f', 'e', 'a', 'c']
console.log(arr1.sort((x,y) => arr2.indexOf(x)  - arr2.indexOf(y)))
kiddorails
  • 12,961
  • 2
  • 32
  • 41
  • @Gerrit0 you are right. I edited my answer to correct the compareFunction. Hopefully it is correct now – kiddorails Jun 24 '18 at 02:28
  • That looks better - I find the comparison rather confusing, and would probably waste time every time I scrolled over it in a code base, but it works :) – Gerrit0 Jun 24 '18 at 02:32
  • I agree, it would take a little bit to understand what's going on, but I don't know if there is going to be a more comprehendible/simple solution. My biggest gripe is the variable names (`x` and `y`) :P Typically sorting uses the `a` and `b`, so this threw me off thinking of it as a cartesian coordinate for no reason other than the variable name. – vol7ron Jun 24 '18 at 03:20
2

The usual (?) short version is O(n2) (assuming all names are unique and exist in both arrays):

var arr1 = [ { "name": "bobby", "occupation": "singer" },
             { "name": "mindy", "occupation": "artist" } ]; 
var arr2 = [ { "name": "mindy", "hobby": "drawing" },
             { "name": "bobby", "hobby": "driving" } ];

var arr2 = arr1.map(a => arr2.find(b => a.name === b.name));

console.log( JSON.stringify(arr1).replace('},', '},\n ') );
console.log( JSON.stringify(arr2).replace('},', '},\n ') );

Sorting both arrays by name is O(n log n) :

var arr1 = [ { "name": "bobby", "occupation": "singer" },
             { "name": "mindy", "occupation": "artist" } ]; 
var arr2 = [ { "name": "mindy", "hobby": "drawing" },
             { "name": "bobby", "hobby": "driving" } ];

arr1.sort((a, b) => a.name.localeCompare(b.name));
arr2.sort((a, b) => a.name.localeCompare(b.name));

console.log( JSON.stringify(arr1).replace('},', '},\n ') );
console.log( JSON.stringify(arr2).replace('},', '},\n ') );

And finally, O(n) version using lookup helper object :

var arr1 = [ { "name": "bobby", "occupation": "singer" },
             { "name": "mindy", "occupation": "artist" } ]; 
var arr2 = [ { "name": "mindy", "hobby": "drawing" },
             { "name": "bobby", "hobby": "driving" } ];

var lookup = arr2.reduce((r, v) => (r[v.name] = v, r), {});
var arr2 = arr1.map(v => lookup[v.name]);

console.log( JSON.stringify(arr1).replace('},', '},\n ') );
console.log( JSON.stringify(arr2).replace('},', '},\n ') );
Slai
  • 22,144
  • 5
  • 45
  • 53
  • With big-O notation, the numeric coefficient has no meaning, so just drop it. Otherwise, good answer. – Patrick Roberts Jun 24 '18 at 03:17
  • @PatrickRoberts I know that for time complexity the coefficient doesn't have a meaning, but wouldn't 2N vs 100N mean something to someone? At first, I was like, yeah I understand why it's not important, but wouldn't it matter when it comes to *micro-optimization*? – vol7ron Jun 24 '18 at 03:23
  • In an algorithm, the coefficient has no unit, so it conveys no information. Does it mean "function calls", "lines of code", "assembly instructions", "bits toggled", what? If you call a function twice instead of once, it's still the same big-O. It doesn't change the _complexity_, just the _proportion_, so it's generally ignored. – Patrick Roberts Jun 24 '18 at 03:29