簡體   English   中英

在JavaScript中通過SQL聯接兩個或多個數組

[英]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應用程序中加載。

將它們加入內存的最簡單方法是什么?

如果您可以修改usersuser_types的填充方式,則可以很快完成此操作。

您需要將usersuser_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時執行此操作。

您在這里不需要任何特殊的東西,只需通過userscharges兩個循環:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM