2016-05-26 13 views
2

論理的にリンクされた配列が少ない1ページのWebアプリケーションがあります。「ユーザー」のレコードは「user_types」のレコードを参照し、「料金」は「ユーザー」、 、など:私は、サーバー上でこのSQLクエリでAPI呼び出しを作成することができます知っている2つ以上の配列をJavaScriptで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 

、私:

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の製品と同様に、リンクされた方法でそれらを表示する必要がありますテーブルがすでにWebアプリケーションにロードされているため、この問題を回避したいと考えています。

メモリに参加させる最も簡単な方法は何ですか?

+0

あなたはライブラリまたは純粋なJSを使用して喜んでいますか?そして、これらの配列にどれくらいのデータがありますか?彼らは巨大ですか? – IMTheNachoMan

+0

あなたはすでに自分の質問に答えています:それをSQLで行います。次に、アプリ内のデータを更新して一致させます。 – SenorAmor

+0

また、配列はどのように生成/生成されていますか?あなたがどのように入力されているかを変更することができれば、あなたが参加する必要があるときにもっと簡単にすることができます。 – IMTheNachoMan

答えて

1

をあなたが最初のユーザーとその種類を処理することによって、わずかにそれを最適化することができますが、それはそれについてですが、これはStrelkiJSで行うことができます。

[ 
    [ 
     {"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 
    ] 
] 
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", 
    }] 
}]) 

結果は、以下の構造のアレイを接合します

+0

これは完璧に見えます。ありがとう! –

0

usersをマップにすると、users['u0001']を使用できます。その後、chargesをループし、users[current_charge.user_id].charges.push(current_charge)を実行します。 usersの各ユーザーは、chargesプロパティを空の配列として初期化する必要があります。 usersアレイをid => userマップにすると、そのことができます。

あなたはuserschargesてちょうど2つのループが、ここでは何も特別なことは必要ありません。

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のものを活用し Aは本当に簡単な解決策は、これを次のようになります。

var joined_data = Object.keys(users_map).map(function (key) { 
    return users_map[key]; 
}); 

あなたはlodashまたは他の同様のライブラリをたくさんきれいに上記のコードを作ることができます。

1

usersuser_typesが入力される方法を変更することができれば、これをかなり早く行うことができます。

あなたはこのような何か持っているので、オブジェクトにusersuser_typesを変更する必要があります:オブジェクトを再構築せずに、これを行うための唯一の方法は、ループフィルタにある

// make users an object with the id as the key 
 
var users = { 
 
\t "u0001" : { name: "John",  user_type_id: "1" }, 
 
\t "u0002" : { name: "Bob",  user_type_id: "1" }, 
 
\t "u0003" : { name: "Alice",  user_type_id: "5" }, 
 
\t "u0004" : { name: "Jennifer", user_type_id: "5" } 
 
}; 
 

 
// same for user_types 
 
var user_types = { 
 
\t "1" : { name: "Regular Clients" }, 
 
\t "5" : { name: "VIP Clients" } 
 
}; 
 

 
var charges = [ 
 
\t { id: "7443", user_id: "u0001", date: "2016-01-01", amount: "3.99", }, 
 
\t { id: "7445", user_id: "u0001", date: "2016-01-01", amount: "4.02", }, 
 
\t { id: "7448", user_id: "u0001", date: "2016-01-01", amount: "6.99", }, 
 
\t { id: "7453", user_id: "u0003", date: "2016-01-01", amount: "3.00", }, 
 
\t { 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) 
 
{ 
 
\t var currentCharge = charges[i]; 
 
\t 
 
\t if(currentCharge.user_id === null) continue; 
 
\t 
 
\t out.push([ 
 
\t \t currentCharge.date, 
 
\t \t currentCharge.amount, 
 
     
 
     // get the current charges user_id and look up the name from users 
 
\t \t users[currentCharge.user_id].name, 
 
     
 
     // same as above but use the user_type_id to get the user_type name 
 
\t \t user_types[users[currentCharge.user_id].user_type_id].name 
 
\t ]); 
 
} 
 

 
console.log(out);

0

を。 小さなライブラリがOKであれば...

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);

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);

関連する問題