如何通过数组中的更多嵌套对象对JavaScript数组进行排序,并抓住顶部?
下面是一个虚拟示例。我有一个对象数组:如何通过数组中的更多嵌套对象对JavaScript数组进行排序,并抓住顶部?,javascript,arrays,Javascript,Arrays,下面是一个虚拟示例。我有一个对象数组: var cars = [ { name: "Hyundai", plans: [ { name: "Something", add-ons: [ { cost: 100 }, { cost: 75 } ] }
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
}
]
}, {...}
]
}
]
我想做的是找到最便宜的两款车,并通过另一个变量引用它们
像这样:
var top2 = findTopTwo(cars);
findTopTwo(arr) {
return arr.sort(function(a, b) {
// My trouble spot
}).slice(0, 2);
}
通过我的简单示例,top2的结果是:
我不得不摆弄这个东西,但这里是它的要点-
var-cars=[{
名称:“现代”,
计划:{
插件:[{
费用:100
}, {
费用:75
}]
}
}, {
名称:“吉普”,
计划:{
插件:[{
费用:50
}, {
费用:75
}]
}
}, {
名称:“别克”,
计划:{
插件:[{
费用:35
}, {
费用:50
}]
}
}];
var top2=FindTop2(汽车);
控制台日志(top2);
函数findTopTwo(arr){
返回arr.sort(函数(a,b){
//此映射输出成本数组:[35,40]
//而Math.min取其中的最小值
var a_max_cost=Math.min.apply(null,a.plans.addons.map(函数(i){i.cost})),
b_max_cost=Math.min.apply(null,b.plans.addons.map(函数(i){i.cost}));
返回a_max_cost-b_max_cost;
})
.切片(0,2);
}
一种简单的方法是首先按价格对插件进行排序(如果你不介意插件的副作用,那么就继续按价格排序)
所以我要做的是将它们全部输入一个数组,然后根据成本对其进行排序。那将是我天真的做法。更理想的解决方案是在给定时间只存储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);
var项目=[];
用于(车辆中的var i){
var car=cars[i];
对于(车内var i[“计划”]){
对于(var j=0;j
这将返回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;
var最大=函数(arr){
if(arr.length<2)返回-1;
返回arr[0]。成本>arr[1]。成本?0:1;
}
var项目=[];
用于(车辆中的var i){
var car=cars[i];
对于(车内var i[“计划”]){
对于(var j=0;j目标成本)
项目[索引]=obj;
}
}
}
退货项目;
这个更有趣的设计将把前两个推到列表中,但它会找到这两个成本中最大的一个,然后检查新的是否比它小。如果新的索引小于项[索引]
,则会将其替换
这将永远不会使数组大于2,因此它占用更少的内存。通过这种方法,您的原始数据将不会被排序或修改
var cars=[{name:“现代”,计划:[{name:“某物”,“附加组件”:[{cost:100},{cost:75}]},
{name:“吉普”,计划:[{name:“某物”,“附加组件”:[{cost:50},{cost:75}]},
{name:“别克”,计划:[{name:“某物”,“附加组件”:[{cost:35},{cost:50}]}];
功能findTopTwo(汽车){
返回汽车地图(
汽车=>
减少(
(计划,计划)=>
计划['add-ons'].reduce((prevAddOn,addOn)=>{
if(prevAddOn.cost>addOn.cost){
prevAddOn.cost=addOn.cost;
}
返回前置加载项;
},上一份计划){
成本:Number.MAX_值,
姓名:car.name
})
)
.sort((a,b)=>a.cost-b.cost)
.slice(0,2)
.map(item=>item.name);
}
控制台日志(findTopTwo(cars))代码>使用@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行将每个cars的插件
数组从低到高排序。第5行根据插件
属性的第一个索引,将汽车
从低到高排序
如果ES6语法令人困惑,我建议使用,然后从前面的两个条目中获取数据
var cars=[{name:“现代”,计划:[{‘附加组件’:[{cost:100},{cost:75}]},{name:“吉普”,计划:[{‘附加组件’:[{cost:50},{cost:75}]}},{name:“别克”,计划:[{‘附加组件’:[{cost:35},{cost:50}]}]}]},
成本=汽车。
地图(功能(a,i){
返回{
索引:i,,
成本:a.计划.减少(功能(r,b){
返回Math.min(r,b['add-ons'].reduce(函数s,c){
返回数学最小值(s,c.成本);
},无穷大);
},无穷大)
};
}).
排序(函数(a,b){返回a.cost-b.cost;}),
top2=cost.slice(0,2).map(函数(a){
返回车[a.指数];
});
控制台日志(top2)代码>
。作为控制台包装{max height:100%!important;top:0;}
您的加载项将有名称,还是只是成本?因为如果你只是存储一个k-v对,那么在数组中存储一个对象是没有意义的。为了简单起见,我将其中的99%剥离出来,所以回答-yes:)plans
是一个对象,而不是数组。我应该在示例代码中包含更多内容。计划不是一个对象。“我将编辑我的问题。”尼纳斯科尔斯道歉。我已经编辑了这个问题。为了简化,我遗漏了需要的内容。为了简化示例代码,我确实犯了一个错误。计划是一个数组。好的,我加了一个便条谢谢。现在就想弄清楚。只是那些脑筋急转弯的人之一。
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;
});