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' } ]
1

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

Comments

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});

Comments

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.