0

I have 2 arrays array1, array2.

  1. array 1 objects: userName, userId
  2. array 2 objects: userId, msg
  3. i want to get array3: userId, userName, msg

Array1:

[{ userName: 'vimal', userId: 789 },
    { userName: 'kabilan', userId: 456 },
    { userName: 'yathavan', userId: 123 }]

Array2:

[ { userId: '123', msg: 'hi' },
{ userId: '789', msg: 'yth' },
{ userId: '789', msg: 'hu' } ]

i want to compare 2 arrays and get output like this. Array3:

[ { userId: '123', userName: 'yathavan', msg: 'hi' },
{ userId: '789', userName: 'vimal', msg: 'yth' },
{ userId: '789', userName: 'vimal', msg: 'hu' } ]
scrowler
  • 24,273
  • 9
  • 60
  • 92
yathavan
  • 2,051
  • 2
  • 18
  • 25
  • possible duplicate of [How can I merge properties of two JavaScript objects dynamically?](http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically) – Ben Fortune Apr 23 '15 at 20:47

3 Answers3

1

I'd make a users array indexed my the userid that contains the username;

var users = [];

for(var i=0; i<arr1.length; i++)
  users[arr1[i].userId] = arr1[i].userName;

now make your output array, and go through the 2nd array. using the users array to insert;

var arr3 = [];

for(var i=0; i<arr2.length; i++)
  arr3.push({userId:arr2[i].userId, userName:users[arr2[i].userId], msg:arr2[i].msg});
Charlie Wynn
  • 921
  • 1
  • 8
  • 22
1

You would do something like this, if userId value was not a String in ary2:

var ary1 =[{userName:'vimal', userId:789}, {userName:'kabilan', userId:456}, {userName:'yathavan', userId:123}];
var ary2 = [{userId:123, msg:'hi'}, {userId:789, msg:'yth'}, {userId:789, msg:'hu'}];
function specialMerge(ar1, ar2){
  var r = [];
  for(var i=0,l=ar1.length; i<l; i++){
    var p = ar1[i];
    for(var n=0,c=ar2.length; n<c; n++){
      var m = ar2[n];
      if(p.userId === m.userId){
        r.push({userId:p.userId, userName:p.userName, msg:m.msg});
      }
    }
  }
  return r;
}
var resultArrayOfObjects = specialMerge(ary1, ary2);
StackSlave
  • 10,613
  • 2
  • 18
  • 35
1

An off-the-shelf, "functional programming" approach:

var users = [{ userName: 'vimal', userId: 789 },
    { userName: 'kabilan', userId: 456 },
    { userName: 'yathavan', userId: 123 }]

var messages = [ { userId: '123', msg: 'hi' },
    { userId: '789', msg: 'yth' },
    { userId: '789', msg: 'hu' } ]

var user_message_list = [];
messages.map(function (message) {
    return users.
        filter(function (user) {
            return user.userId == message.userId
        }).
        map(function (user) {
            return {
                "userId": user.userId,
                "userName": user.userName,
                "msg": message.msg
            }
        })
})
.forEach(function (item) { // eliminate nested layers 
    user_message_list.push.apply(user_message_list, item)
})

JSFiddle Functional


Explanation:

Two arrays of objects, one a list of users, and the other a list of messages by some of those users.

You're wanting to flesh out a report of the messages showing the usernames, so start with the messages array and loop through it. Now, for each message loop through the users list and retrieve the corresponding username.

The "loopy" approach is like this:

var messages_users = []
var message_user = {}
for (ii=0; ii < messages.length; ii++) {
    message_user = {
        "userId": messages[ii].userId,
        "msg": messages[ii].msg
    }
    for (iii=0; iii < users.length; iii++) {
        if ( messages[ii].userId == users[iii].userId ) {
            message_user.userName = users[iii].userName
        }
    }
    messages_users.push(message_user)
}

JSFiddle Loopy

Alternatively, using Functional Programming concepts, start by maping a function to each item in the messages array. That function takes the users array and filters it to find the corresponding user object for the current message, and map on that result to combine the current message information with the filtered user result. At this point you have an object wrapped in an array, since the map and filter methods return arrays. Therefore, the final operation is to loop using the forEach method to remove the extra array layer. Some JavaScript libraries have a concatAll or better yet concatMap method that hides that extra loop. In that case you'd have something like this:

var user_message_list = messages.
    concatMap(function (message) {
        return users.
            filter(function (user) {
                return user.userId == message.userId
            }).
            map(function (user) {
                return {
                    "userId": user.userId,
                    "userName": user.userName,
                    "msg": message.msg
                }
            })
})

The benefit here is tighter coupling between the language nomenclature and the procedural concepts. For example: filter(... vs. for (i=0; ... if ( arr[i] ===.... Both constructs loop and select items based on criteria, hence filter.

More on Functional Programming in JavaScript

bloodyKnuckles
  • 11,551
  • 3
  • 29
  • 37