簡體   English   中英

如何通過數組中更多嵌套對象對JavaScript數組進行排序,並搶占頂部###?

[英]How to sort a JavaScript array by more nested objects in arrays and grab the top ###?

這是一個虛擬的例子。 我有一個對象數組:

var cars = [
  { 
    name: "Hyundai",
    plans: [
      {
        name: "Something",
        add-ons: [
            {
               cost: 100
            },
            {
               cost: 75
            }
        ] 
      }, { ... }
    ]
  },
  { 
    name: "Jeep",
    plans: [
      {
        name: "Something",
        add-ons: [
            {
               cost: 50
            },
            {
               cost: 75
            }
        ] 
      }, { ... }
    ]
  },
  { 
    name: "Buick",
    plans: [
      {
        name: "Something",
        add-ons: [
            {
               cost: 35
            },
            {
               cost: 50
            }
        ] 
      }, {...}
    ]
  }
]

我想做的是找到最便宜的前2名汽車,並通過另一個變量引用它們。

像這樣:

var top2 = findTopTwo(cars);

findTopTwo(arr) {
  return arr.sort(function(a, b) {
    // My trouble spot
  }).slice(0, 2);
}

在我的簡單示例中,top2的結果為:

  1. 別克(最便宜的附加組件是$ 35,用於與進行比較的值)
  2. 吉普車(最便宜的附加組件是$ 50,用於與進行比較的價值)

因此,我要做的就是將它們全部饋入一個數組,然后根據成本對其進行排序。 那將是我的幼稚方法。 最佳的解決方案是在給定時間僅存儲2個對象,而不是所有項目的列表。

天真的方法很簡單:

var items = [];
for ( var i in cars ){
  var car = cars[i];
  for (var i in car["plans"]){
    for (var j = 0; j < car["plans"][i]["add-ons"]){
      items.push({"name": car.name, "cost": car["plans"][i]["add-ons"][j]["cost"]});
    }
  }
}
return items.sort(function(a,b){ return a.cost < b.cost }).slice(0,2);

那將返回2個對象的列表,該對象包含汽車的名稱和成本。 更有效的方法是執行以下操作:

var biggest = function(arr){
  if (arr.length < 2 ) return -1;
  return arr[0].cost > arr[1].cost ? 0 : 1;
}
var items = [];
for ( var i in cars ){
  var car = cars[i];
  for (var i in car["plans"]){
    for (var j = 0; j < car["plans"][i]["add-ons"]){
      var obj = {"name": car.name, "cost": car["plans"][i]["add-ons"][j]["cost"]};
    }

    var index = biggest(items)
    if (index < 0){
      items.push(obj);
    }else{
      if (items[index].cost > obj.cost)
        items[index] = obj;
    }

  }
}
return items;

這種更有趣的設計會將前兩個成本推入列表,但隨后它將找到這兩個成本中的最大成本,然后檢查新成本是否小於它。 如果新的小於item[index] ,它將被替換。

該數組永遠不會大於2,因此占用的內存更少

另一種方法。 通過這種方法,您的原始數據將不會被排序或修改。

 var cars=[{name:"Hyundai",plans:[{name:"Something","add-ons":[{cost:100},{cost:75}]}]}, {name:"Jeep",plans:[{name:"Something","add-ons":[{cost:50},{cost:75}]}]}, {name:"Buick",plans:[{name:"Something","add-ons":[{cost:35},{cost:50}]}]}]; function findTopTwo(cars) { return cars.map( car => car.plans.reduce( (prevPlan, plan) => plan['add-ons'].reduce((prevAddOn, addOn) => { if (prevAddOn.cost > addOn.cost) { prevAddOn.cost = addOn.cost; } return prevAddOn; }, prevPlan), { cost: Number.MAX_VALUE, name: car.name }) ) .sort((a, b) => a.cost - b.cost) .slice(0, 2) .map(item => item.name); } console.log(findTopTwo(cars)); 

我不得不試玩這個對象,但這是要點-

 var cars = [{ name: "Hyundai", plans: { addons: [{ cost: 100 }, { cost: 75 }] } }, { name: "Jeep", plans: { addons: [{ cost: 50 }, { cost: 75 }] } }, { name: "Buick", plans: { addons: [{ cost: 35 }, { cost: 50 }] } }]; var top2 = findTopTwo(cars); console.log(top2); function findTopTwo(arr) { return arr.sort(function (a, b) { // this map outputs array of costs: [35, 40] // and Math.min takes the lowest value of each var a_max_cost = Math.min.apply(null, a.plans.addons.map(function(i){i.cost})), b_max_cost = Math.min.apply(null, b.plans.addons.map(function(i){i.cost})); return a_max_cost - b_max_cost; }) .slice(0, 2); } 

基本上,您需要在sort函數中返回ab ,其中ab是最低附加值。 因此,我在比較時計算了兩輛車的最大值,並使用這些值來決定哪輛車去哪兒。

編輯:我看到您已經更新了JS對象,答案應該類似於min,您只需要弄清楚對ab使用哪個plan 您可以執行類似於我對Math.max函數的使用

一種簡單的實現方法是先按價格對插件進行排序(如果您不介意插件的副作用,然后按價格進行排序)。

function findTopTwo(arr) {
  arr.forEach(function (elem) {
    elem.plans.addons = elem.plans.addons.sort(function (a, b) {
      return a.cost > b.cost;
    });
  });
  return arr.sort(function(a, b) {
    return a.plans.addons[0].cost > b.plans.addons[0].cost;
  }).slice(0, 2);
}

jsbin示例

使用@casraf的數據:

const sortedCars = cars.map(car => {
    car.plans.addons.sort((a, b) =>  a.cost - b.cost);
    return car;
}).sort((a, b) => {
    return a.plans.addons[0].cost - b.plans.addons[0].cost;
});

第2行按從低到高的順序對每輛汽車的addons排序。 第5行根據其相應的addons屬性的第一個索引將cars從低到高排序。

如果ES6語法令人困惑, 這是對ES5的翻譯

我建議對地圖進行排序 ,然后選擇前2個條目並從cars獲取數據。

 var cars = [{ name: "Hyundai", plans: [{ 'add-ons': [{ cost: 100 }, { cost: 75 }] }] }, { name: "Jeep", plans: [{ 'add-ons': [{ cost: 50 }, { cost: 75 }] }] }, { name: "Buick", plans: [{ 'add-ons': [{ cost: 35 }, { cost: 50 }] }] }], cost = cars. map(function (a, i) { return { index: i, cost: a.plans.reduce(function (r, b) { return Math.min(r, b['add-ons'].reduce(function (s, c) { return Math.min(s, c.cost); }, Infinity)); }, Infinity) }; }). sort(function (a, b) { return a.cost - b.cost; }), top2 = cost.slice(0, 2).map(function (a) { return cars[a.index]; }); console.log(top2); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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