[英]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的結果為:
因此,我要做的就是將它們全部饋入一個數組,然后根據成本對其進行排序。 那將是我的幼稚方法。 最佳的解決方案是在給定時間僅存儲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
,其中a
和b
是最低附加值。 因此,我在比較時計算了兩輛車的最大值,並使用這些值來決定哪輛車去哪兒。
編輯:我看到您已經更新了JS對象,答案應該類似於min,您只需要弄清楚對a
和b
使用哪個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);
}
使用@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.