根据另一个数组中的数据对数组进行排序

Sim*_*ler 8 javascript arrays sorting

我有两个对象数组,如下所示:

items = [{"id":"5","tobuy":"1","name":"pop"},
         {"id":"6","tobuy":"1","name":"fish"},
         {"id":"7","tobuy":"0","name":"soda"}]
pkgs =  [{"item_id":"5","store":"Market","aisle":"3"},
         {"item_id":"6","store":"Market","aisle":"2"},
         {"item_id":"6","store":"Dept","aisle":"8"},
         {"item_id":"7","store":"Market","aisle":"4"}]
Run Code Online (Sandbox Code Playgroud)

我正在尝试对items数组进行排序,但我想利用pkgs数组中的数据.
pkgs数组中的"item_id"字段对应于items数组中的"id"字段.
例如,我想排序:

  • 首先按降序排序"tobuy"
  • 然后通过"商店"
  • 然后通过"过道"
  • 然后通过"名字"

虽然item_id和id在两个数组之间对应,但是没有1对1的关系.可能有0个或更多pkgs对应于任何给定项目.

(如果我有一个数据库,我只会加入表,但在JavaScript中我只有两个相关的数组).

我不确定如何构建比较器函数并传入第二个数组.

谢谢你的帮助.

pla*_*alx 4

也许是这样的?

items = items.map(function (item, index) {
    return {
        item: item,
        pkg: pkgs[index] //I assumed associated pkgs were at the same index
    };
}).sort(function (a, b) {
   var pkgA = a.pkg, pkgB = b.pkg, r;

   r = +b.item.tobuy - +a.item.tobuy;

   if (r !== 0) return r;

   r = pkgA.store < pkgB.store? -1 : (pkgA.store === pkgB.store? 0 : 1);

   if (r !== 0) return r;

   r = +pkgA.aisle - +pkgB.aisle;

   if (r !== 0) return r;

   return pkgA.name < pkgB.name? -1 : (pkgA.name === pkgB.name? 0 : 1);

}).map(function (item) {
    return item.item;
});
Run Code Online (Sandbox Code Playgroud)

您还可以创建一个查找映射,以便直接从排序函数快速检索关联的包,而不是合并数据。

例如

var pkgsMap = pkgs.reduce(function (res, pkg) {
    res[pkg.item_id] = pkg;
    return res;
}, {});
Run Code Online (Sandbox Code Playgroud)

然后在排序函数中你可以这样做:

var pkgA = pkgsMap[a.id], pkgB = pkgsMap[b.id];
Run Code Online (Sandbox Code Playgroud)

编辑:

实际上 pkgs 数组中还有另一个字段,称为“ppu”,它是每单位的价格。将使用最低的 ppu。

您可以使用以下代码构建包映射,然后使用排序函数中的映射来检索关联的包(如上所述)并实现排序算法。

var pkgsMap = pkgs.sort(function (a, b) {
    //not sure what ppu is so I sort it as a string
    return a.ppu < b.ppu? -1 : Number(a.ppu > b.ppu);
}).reduce(function (res, pkg) {
    if (!(pkg.item_id in res)) res[pkg.item_id] = pkg;
    return res;
}, {});
Run Code Online (Sandbox Code Playgroud)