让我们考虑一下如何在 SQL 中执行此操作:
SELECT * FROM items INNER JOIN pkgs ON items.id = pkgs.item_id
ORDER BY tobuy DESC, store, aisle, name
以下答案演示了如何在 JavaScript 中实现内连接和等值连接:
function equijoin(primary, foreign, primaryKey, foreignKey, select) {
var m = primary.length, n = foreign.length, index = [], c = [];
for (var i = 0; i < m; i++) { // loop through m items
var row = primary[i];
index[row[primaryKey]] = row; // create an index for primary table
}
for (var j = 0; j < n; j++) { // loop through n items
var y = foreign[j];
var x = index[y[foreignKey]]; // get corresponding row from primary
c.push(select(x, y)); // select only the columns you need
}
return c;
}
现在可以使用equijoin
加入了items
,pkgs
如下:
equijoin(items, pkgs, "id", "item_id", function (item, pkg) {
return {
id: +item.id,
tobuy: +item.tobuy,
store: pkg.store,
aisle: +pkg.aisle,
name: item.name
};
});
请注意,我通过将一元运算符应用于数字来强制item.id
,item.tobuy
和。pkg.aisle
+
现在我们加入了两个表,我们需要对它们进行排序。要对表格进行排序,我们使用内置的数组sort
方法:
.sort(function (a, b) {
// ORDER BY tobuy DESC
var aTobuy = a.tobuy, bTobuy = b.tobuy;
if (aTobuy < bTobuy) return 1;
if (aTobuy > bTobuy) return -1;
// ORDER BY store
var aStore = a.store, bStore = b.store;
if (aStore < bStore) return -1;
if (aStore > bStore) return 1;
// ORDER BY aisle
var aAisle = a.aisle, bAisle = b.aisle;
if (aAisle < bAisle) return -1;
if (aAisle > bAisle) return 1;
// ORDER BY name
var aName = a.name, bName = b.name;
if (aName < bName) return -1;
if (aName > bName) return 1;
// keep them unchanged
return a.id - b.id;
});
该sort
方法不稳定(即它可能不会保留输入列表中具有相同排序值的项目的排序)。因此,为了解决这个限制,我们a.id - b.id
作为最后一个语句返回。
另请注意,我们正在使用<
and比较所有值(无论是字符串还是数字) >
。字符串是按字典顺序比较的,而数字是按数字比较的。
放在一起的代码如下:
var table = equijoin(items, pkgs, "id", "item_id", function (item, pkg) {
return {
id: +item.id,
tobuy: +item.tobuy,
store: pkg.store,
aisle: +pkg.aisle,
name: item.name
};
}).sort(function (a, b) {
var aTobuy = a.tobuy, bTobuy = b.tobuy;
if (aTobuy < bTobuy) return 1;
if (aTobuy > bTobuy) return -1;
var aStore = a.store, bStore = b.store;
if (aStore < bStore) return -1;
if (aStore > bStore) return 1;
var aAisle = a.aisle, bAisle = b.aisle;
if (aAisle < bAisle) return -1;
if (aAisle > bAisle) return 1;
var aName = a.name, bName = b.name;
if (aName < bName) return -1;
if (aName > bName) return 1;
return a.id - b.id;
});
不如 SQL 简洁吗?无论如何,请自行查看演示:http: //jsfiddle.net/7ZG96/
编辑:如果您只想要id
,tobuy
和列,那么您可以使用如下name
方式从排序表中提取它:map
table.map(function (item) {
return {
id: item.id,
tobuy: item.tobuy,
name: item.name
};
});
这对应于以下 SQL 查询:
SELECT id, tobuy, name FROM (SELECT * FROM items INNER JOIN pkgs
ON items.id = pkgs.item_id ORDER BY tobuy DESC, store, aisle, name)
查看更新的演示:http: //jsfiddle.net/7ZG96/1/