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 map
ing a function to each item in the messages
array. That function takes the users
array and filter
s 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