[英]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.