我有一个页面很少的网页应用程序,这些数组在逻辑上是链接的:来自"用户"是指" user_types"," charge"是指"用户"等:
var users = [
{ id: "u0001", name: "John", user_type_id: "1" },
{ id: "u0002", name: "Bob", user_type_id: "1" },
{ id: "u0003", name: "Alice", user_type_id: "5" },
{ id: "u0004", name: "Jennifer", user_type_id: "5" },
// ... more
];
var user_types = [
{ id: "1", name: "Regular Clients"},
{ id: "5", name: "VIP Clients"},
// ... more
];
var charges = [
{ id: "7443", user_id: "u0001", date: "2016-01-01", amount: "3.99", },
{ id: "7445", user_id: "u0001", date: "2016-01-01", amount: "4.02", },
{ id: "7448", user_id: "u0001", date: "2016-01-01", amount: "6.99", },
{ id: "7453", user_id: "u0003", date: "2016-01-01", amount: "3.00", },
{ id: "7469", user_id: null , date: "2016-01-01", amount: "3.99", },
// ... more
];
我需要以链接的方式显示它们,类似于以下SQL的产品:
SELECT
charges.date,
charges.amount,
users.name,
user_types.name
FROM
charges
LEFT OUTER JOIN users ON users.id = charges.user_id
LEFT OUTER JOIN user_types ON user_types.id = users.user_type_id
我知道我可以在服务器上使用此SQL查询创建API调用,但我想避免这种情况,因为表已经加载到Web应用程序中。
在内存中加入它们的最简单方法是什么?
答案 0 :(得分:1)
如果您可以修改users
和user_types
的填充方式,那么您可以很快完成此操作。
您需要将users
和user_types
更改为对象,以便您拥有以下内容:
// make users an object with the id as the key
var users = {
"u0001" : { name: "John", user_type_id: "1" },
"u0002" : { name: "Bob", user_type_id: "1" },
"u0003" : { name: "Alice", user_type_id: "5" },
"u0004" : { name: "Jennifer", user_type_id: "5" }
};
// same for user_types
var user_types = {
"1" : { name: "Regular Clients" },
"5" : { name: "VIP Clients" }
};
var charges = [
{ id: "7443", user_id: "u0001", date: "2016-01-01", amount: "3.99", },
{ id: "7445", user_id: "u0001", date: "2016-01-01", amount: "4.02", },
{ id: "7448", user_id: "u0001", date: "2016-01-01", amount: "6.99", },
{ id: "7453", user_id: "u0003", date: "2016-01-01", amount: "3.00", },
{ id: "7469", user_id: null , date: "2016-01-01", amount: "3.99", }
];
// now you can just loop through and use object key lookups:
var out = [];
for(var i = 0, numCharges = charges.length; i < numCharges; ++i)
{
var currentCharge = charges[i];
if(currentCharge.user_id === null) continue;
out.push([
currentCharge.date,
currentCharge.amount,
// get the current charges user_id and look up the name from users
users[currentCharge.user_id].name,
// same as above but use the user_type_id to get the user_type name
user_types[users[currentCharge.user_id].user_type_id].name
]);
}
console.log(out);
&#13;
答案 1 :(得分:1)
如果小型库可以,可以使用StrelkiJS:
完成config.active_record.raise_in_transactional_callbacks = true
结果将加入以下结构数组:
var users = new StrelkiJS.IndexedArray();
users.loadArray([
{ id: "u0001", name: "John", user_type_id: "1" },
{ id: "u0002", name: "Bob", user_type_id: "1" },
{ id: "u0003", name: "Alice", user_type_id: "5" },
{ id: "u0004", name: "Jennifer", user_type_id: "5" },
// ... more
]);
var user_types = new StrelkiJS.IndexedArray();
user_types.loadArray([
{ id: "1", name: "Regular Clients"},
{ id: "5", name: "VIP Clients"},
// ... more
]);
var charges = new StrelkiJS.IndexedArray();
charges.loadArray([
{ id: "7443", user_id: "u0001", date: "2016-01-01", amount: "3.99", },
{ id: "7445", user_id: "u0001", date: "2016-01-01", amount: "4.02", },
{ id: "7448", user_id: "u0001", date: "2016-01-01", amount: "6.99", },
{ id: "7453", user_id: "u0003", date: "2016-01-01", amount: "3.00", },
{ id: "7469", user_id: null , date: "2016-01-01", amount: "3.99", },
// ... more
]);
var result = charges.query([{
from_col: "user_id",
to_table: users,
to_col: "id",
type: "outer",
join: [{
from_col: "user_type_id",
to_table: user_types,
to_col: "id",
type: "outer",
}]
}])
答案 2 :(得分:1)
此提案采用IMTheNachoMan解决方案,扩展了来自给定数据的生成必需对象。
它包含charges
的所有行,因为使用SQL时,也会返回行。
此处测试null
值的问题,然后返回null
。
var users = [{ id: "u0001", name: "John", user_type_id: "1" }, { id: "u0002", name: "Bob", user_type_id: "1" }, { id: "u0003", name: "Alice", user_type_id: "5" }, { id: "u0004", name: "Jennifer", user_type_id: "5" }],
user_types = [{ id: "1", name: "Regular Clients" }, { id: "5", name: "VIP Clients" }],
charges = [{ id: "7443", user_id: "u0001", date: "2016-01-01", amount: "3.99", }, { id: "7445", user_id: "u0001", date: "2016-01-01", amount: "4.02", }, { id: "7448", user_id: "u0001", date: "2016-01-01", amount: "6.99", }, { id: "7453", user_id: "u0003", date: "2016-01-01", amount: "3.00", }, { id: "7469", user_id: null, date: "2016-01-01", amount: "3.99", }],
user = Object.create(null),
type = Object.create(null),
result;
users.forEach(function (u) {
user[u.id] = u;
});
user_types.forEach(function (t) {
type[t.id] = t;
});
result = charges.map(function (charge) {
return {
'charges.date': charge.date,
'charges.amount': charge.amount,
'users.name': charge.user_id === null ? null : user[charge.user_id].name,
'user_types': charge.user_id === null ? null : type[user[charge.user_id].user_type_id].name,
};
});
console.log(result);
&#13;
答案 3 :(得分:0)
制作users
地图,以便您使用users['u0001']
。然后循环浏览charges
并执行users[current_charge.user_id].charges.push(current_charge)
。 users
中的每个用户都应将charges
属性初始化为空数组。将users
数组转换为id => user
地图时,可以执行此操作。
此处您不需要任何特殊内容,只需通过users
和charges
两个循环:
var users_map = {};
var i;
for(i = 0; i < users.length; i++) {
users_map[users[i].id] = users[i];
users_map[users[i].id].charges = [];
}
for(i = 0; i < charges.length; i++) {
users_map[charge[i].user_id].charges.push(charge[i]);
}
如果您确实需要最终的“结果”作为数组而不是地图,则可以再次遍历users_map
并将其转换为数组。
一个非常简单的解决方案利用现代JS的东西是这样的:
var joined_data = Object.keys(users_map).map(function (key) {
return users_map[key];
});
您可以使用lodash或其他类似的库使上述代码更漂亮。
答案 4 :(得分:0)
在不重构对象的情况下执行此操作的唯一方法是循环和过滤。 您可以通过首先处理用户及其类型来稍微优化它,但这就是它......
var users = [
{ id: "u0001", name: "John", user_type_id: "1" },
{ id: "u0002", name: "Bob", user_type_id: "1" },
{ id: "u0003", name: "Alice", user_type_id: "5" },
{ id: "u0004", name: "Jennifer", user_type_id: "5" },
// ... more
];
var user_types = [
{ id: "1", name: "Regular Clients"},
{ id: "5", name: "VIP Clients"},
// ... more
];
var charges = [
{ id: "7443", user_id: "u0001", date: "2016-01-01", amount: "3.99", },
{ id: "7445", user_id: "u0001", date: "2016-01-01", amount: "4.02", },
{ id: "7448", user_id: "u0001", date: "2016-01-01", amount: "6.99", },
{ id: "7453", user_id: "u0003", date: "2016-01-01", amount: "3.00", },
{ id: "7469", user_id: null , date: "2016-01-01", amount: "3.99", },
// ... more
];
// pre-process users
var usersPlusTypes = users.map(function(u) {
var foundUserTypes = user_types.filter(function(ut) {
return ut.id == u.user_type_id;
});
return {
id: u.id,
user: u,
userType: foundUserTypes.length ? foundUserTypes[0] : null
}
})
// now link charges to users
var results = charges.map(function(c) {
var user = usersPlusTypes.filter(function(upt) {
return upt.id == c.user_id;
});
return {
date: c.date,
amount: c.amount,
userName: user.length ? user[0].user.name : null,
userTypeName: user.length && user[0].userType ? user[0].userType.name : null,
};
});
console.log(results);