[英]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) }
你可以做這樣的事情
min
和max
不可用,請使用當前值初始化 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.