[英]SQL-joining of two or more arrays in JavaScript
我有一個包含少量數組的一頁Web應用程序,這些數組在邏輯上是鏈接的:“用戶”中的記錄是指“用戶類型”中的記錄,“收費”是指“用戶”中的記錄,依此類推:
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應用程序中加載。
將它們加入內存的最簡單方法是什么?
如果您可以修改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);
如果小型庫可以,則可以使用StrelkiJS完成:
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",
}]
}])
結果將加入以下結構的數組:
[
[
{"id":"7443","user_id":"u0001","date":"2016-01-01","amount":"3.99"},
{"id":"u0001","name":"John","user_type_id":"1"},
{"id":"1","name":"Regular Clients"}
],
[
{"id":"7445","user_id":"u0001","date":"2016-01-01","amount":"4.02"},
{"id":"u0001","name":"John","user_type_id":"1"},
{"id":"1","name":"Regular Clients"}
],
[
{"id":"7448","user_id":"u0001","date":"2016-01-01","amount":"6.99"},
{"id":"u0001","name":"John","user_type_id":"1"},
{"id":"1","name":"Regular Clients"}
],
[
{"id":"7453","user_id":"u0003","date":"2016-01-01","amount":"3.00"},
{"id":"u0003","name":"Alice","user_type_id":"5"},
{"id":"5","name":"VIP Clients"}
],
[
{"id":"7469","user_id":null,"date":"2016-01-01","amount":"3.99"},
null,
null
]
]
該提議具有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);
使users
成為地圖,以便可以使用users['u0001']
。 然后遍歷charges
並執行users[current_charge.user_id].charges.push(current_charge)
。 在每個用戶users
應該有一個charges
初始化為空數組屬性。 您可以在將users
數組轉換為id => user
map時執行此操作。
您在這里不需要任何特殊的東西,只需通過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或其他類似的庫使上面的代碼更漂亮。
無需重組對象即可執行此操作的唯一方法是循環和過濾。 您可以通過先處理用戶及其類型來對其進行稍微優化,但這僅是...
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.