簡體   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