繁体   English   中英

比较对象的JavaScript数组以同时获得具有2个属性的最小值/最大值

[英]Compare JavaScript Array of Objects to Get Min / Max With 2 Properties At the Same Time

var items = [
    {"ID": 1, "Cost": 200, "Count": 4},
    {"ID": 2, "Cost": 1000, "Count": 2},
    {"ID": 3, "Cost": 50, "Count": 10},
    {"ID": 4, "Cost": 50, "Count": 10},
    {"ID": 5, "Cost": 50, "Count": 10},
    {"ID": 6, "Cost": 50, "Count": 8}
]

我想获得成本最低的项目,如果其中许多成本相同,我想获得计数最高的项目,如果还有多个,我希望获得一个随机项目。

var lowestCost = items.reduce(function(prev, curr) {
    return prev.Cost < curr.Cost ? prev : curr;
});

这是获得最低成本的方法,同时进行其他比较的任何简单方法是吗?

一个不太随机的解决方案:

 const items = [ {"ID": 1, "Cost": 200, "Count": 4}, {"ID": 2, "Cost": 1000, "Count": 2}, {"ID": 3, "Cost": 50, "Count": 10}, {"ID": 4, "Cost": 50, "Count": 10}, {"ID": 5, "Cost": 50, "Count": 10}, {"ID": 6, "Cost": 50, "Count": 8} ]; const computeLowestCost = () => { return items.reduce(function(prev, curr) { const isEqualPriceAndCount = (prev.Cost === curr.Cost) && (prev.Count === curr.Count); if (isEqualPriceAndCount) { // return a random item if price and count are the same return (!!Math.round(Math.random())) ? prev : curr; } return !!((prev.Cost < curr.Cost) || (prev.Count > curr.Count)) ? prev : curr; }); } const lowestCost = computeLowestCost(); console.log(lowestCost); // Randomness...is not that random because // 1st item has 1/2 * 1/2 * 1/2 chance to remain // 2nd item has 1/2 * 1/2 chance to remain // 3rd item has 1/2 chance to remain const results = {}; for (let i = 0; i < 1000000;i++) { const res = computeLowestCost(); results[res.ID]= !!results[res.ID] ? ++results[res.ID] : 1; } console.log(results) 

更加随机的解决方案:

 const items = [ {"ID": 1, "Cost": 200, "Count": 4}, {"ID": 2, "Cost": 1000, "Count": 2}, {"ID": 3, "Cost": 50, "Count": 10}, {"ID": 4, "Cost": 50, "Count": 10}, {"ID": 5, "Cost": 50, "Count": 10}, {"ID": 6, "Cost": 50, "Count": 8} ]; const shuffle = (array) => array.sort(() => Math.random() - 0.5); const computeLowestCost = () => { shuffle(items); return items.reduce(function(prev, curr) { const isEqualPriceAndCount = (prev.Cost === curr.Cost) && (prev.Count === curr.Count); if (isEqualPriceAndCount) { // return a random item if price and count are the same return (!!Math.round(Math.random())) ? prev : curr; } return !!((prev.Cost < curr.Cost) || (prev.Count > curr.Count)) ? prev : curr; }); } const lowestCost = computeLowestCost(); console.log(lowestCost); // Randomness...almost equally distributed const results = {}; for (let i = 0; i < 1000000;i++) { const res = computeLowestCost(); results[res.ID]= !!results[res.ID] ? ++results[res.ID] : 1; } console.log(results) // For more randomness we could shuffle the array initially 

您可以获取缩减数据集的数组,然后获取一个随机对象。

 var items = [{ ID: 1, Cost: 200, Count: 4 }, { ID: 2, Cost: 1000, Count: 2 }, { ID: 3, Cost: 50, Count: 10 }, { ID: 4, Cost: 50, Count: 10 }, { ID: 5, Cost: 50, Count: 10 }, { ID: 6, Cost: 50, Count: 8 }], result = items.reduce((r, o) => { if (!r || r[0].Cost > o.Cost || r[0].Cost === o.Cost && r[0].Count < o.Count) { return [o]; } if (r[0].Cost === o.Cost && r[0].Count === o.Count) { r.push(o); } return r; }, null); console.log(result[Math.floor(Math.random() * result.length)]); // random console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

因此,不是那么简单的方法是只在事后再执行另一个三元运算来确定它是否等于或大于。 然后,我们将有另一个三元数来找出哪个具有更高的计数等等。

var items = [
    {"ID": 1, "Cost": 200, "Count": 4},
    {"ID": 2, "Cost": 1000, "Count": 2},
    {"ID": 3, "Cost": 50, "Count": 10},
    {"ID": 4, "Cost": 50, "Count": 10},
    {"ID": 5, "Cost": 50, "Count": 10},
    {"ID": 6, "Cost": 50, "Count": 8}
]

var lowestCost = items.reduce(function(prev, curr) {
    return prev.Cost < curr.Cost ? prev: (prev.Cost == curr.Cost ? (prev.Count > curr.Count ? prev: curr) : curr);
});

创建一个包含成本的数组,并创建一个包含计数的数组。 从成本中选择最小值,从计数中选择最大值。 过滤数组并进行比较。 该代码是不言自明的。 评论以进一步解释

 var items = [ {"ID": 1, "Cost": 200, "Count": 4}, {"ID": 2, "Cost": 1000, "Count": 2}, {"ID": 3, "Cost": 50, "Count": 10}, {"ID": 4, "Cost": 50, "Count": 10}, {"ID": 5, "Cost": 50, "Count": 10}, {"ID": 6, "Cost": 50, "Count": 8} ] let costs = items.map(objs => Number(objs["Cost"])) // get all the costs from the items let counts = items.map(objs => Number(objs["Count"])) //.. get all the counts from the items let mincost = Math.min(...costs) // get the mininum cost let maxcount = Math.max(...counts) // get the max cost let answer = items.filter((objs) => { // filter the items array if (objs["Cost"] == mincost){ // if the cost is minimum if (objs["Count"] == maxcount) { // if the count is maximum return objs // return the object } } }) if (answer.length >= 1) { // if more than one answers let random = answer[Math.floor(Math.random() * answer.length)]; // return a random value console.log(random); }else{ console.log(answer) // else just log the value } 

Math.floor(Math.random() * answer.length)这为您提供了一个在数组长度范围内的随机数。 因此,您只需将其插入数组的选择器即可。

这转化为

 var items = [{"ID": 1, "Cost": 200, "Count": 4},{"ID": 2, "Cost": 1000, "Count": 2},{"ID": 3, "Cost": 50, "Count": 10},{"ID": 4, "Cost": 50, "Count": 10},{"ID": 5, "Cost": 50, "Count": 10},{"ID": 6, "Cost": 50, "Count": 8}] let mincost = Math.min(...items.map(objs => Number(objs["Cost"]))) let maxcount = Math.max(...items.map(objs => Number(objs["Count"]))) let answer = items.filter(objs => objs["Cost"] == mincost && objs["Count"] == maxcount) if (answer.length >= 1) { let random = answer[Math.floor(Math.random() * answer.length)]; console.log(random); }else{ console.log(answer) } 

你可以做这样的事情

  • 随机数组
  • 遍历随机数组,使用对象保存最大值和最小值
  • 如果minmax不可用,请使用当前值初始化
  • 检查价格是否小于或等于最小值,如果价格相等且计数相同,则将其他价格更新为新值
  • 以相同的方式检查是否大于或等于最大值并相应地更新

 var items = [ {"ID": 1, "Cost": 200, "Count": 4}, {"ID": 2, "Cost": 1000, "Count": 2}, {"ID": 3, "Cost": 50, "Count": 10}, {"ID": 4, "Cost": 50, "Count": 10}, {"ID": 5, "Cost": 50, "Count": 10}, {"ID": 6, "Cost": 50, "Count": 8} ] let randomizeArray = _.shuffle(items) let op = randomizeArray.reduce((op,inp)=>{ op.max = op.max || inp op.min = op.min || inp if(inp.Cost <= op.min.Cost){ if((op.min.Cost > inp.Cost) || (op.min.Count < inp.Count)){ op.min = inp } } if(inp.Cost >= op.max.Cost){ if((op.max.Cost < inp.Cost) || (op.max.Count < inp.Count)){ op.max = inp } } return op },{}) console.log(op) 
 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script> 

items = items.sort((a,b) => a.Cost < b.Cost ? -1 : (a.Cost == b.Cost ? 0 : 1))
items = items.filter(item => item.Count == items[0].Count)
return items.length != 0 ? items[0] : null

这会做到的

  prev.Cost === curr.Cost && prev.Count > curr.Count || prev.Cost < curr.Cost
     ? prev
     :  curr

或者更聪明:

  ((prev.Cost - curr.Cost) || (prev.Count - curr.Count)) < 0 
     ? curr
     : prev

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM