现成的“函数式编程”方法:
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
解释:
两个对象数组,一个是用户列表,另一个是其中一些用户的消息列表。
您想要充实显示用户名的消息报告,因此从 messages 数组开始并循环遍历它。现在,对于每个消息,循环通过users 列表并检索相应的用户名。
“循环”的方法是这样的:
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
或者,使用函数式编程概念,从 map 为 messages 数组中的每个项目添加一个函数开始。该函数采用users 数组和filters 来查找当前消息的相应用户对象,并在该结果上使用map 以将当前消息信息与过滤后的用户结果相结合。此时,您将对象包装在数组中,因为 map 和 filter 方法返回数组。因此,最后的操作是循环使用forEach方法去除多余的数组层。一些 JavaScript 库有一个 concatAll 或更好的 concatMap 方法来隐藏那个额外的循环。在这种情况下,你会有这样的事情:
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
}
})
})
这里的好处是语言命名法和程序概念之间的耦合更紧密。例如:filter(... 与 for (i=0; ... if ( arr[i] ===...。两种构造都基于标准循环和选择项目,因此filter。
更多关于Functional Programming in JavaScript