简体   繁体   中英

Get matched range item from array of objects javascript

I have one array which is named as tiers and one quantity variable. Now I am trying to get the matched range value from my tier array. Based on the matched result I want to calculate the discount. I tried to with find method but it gives me an unexpected ouput.

Actual output {id: 1, discount_percent:0, quantity:6, title:"Tier 1"}

Expeceted Output {id: 3, discount_percent:10, quantity:10, title:"Tier 3"}

let tiers = [
   {id: 1, discount_percent:0, quantity:6, title:"Tier 1"},
   {id: 2, discount_percent:5, quantity:8, title:"Tier 2"},
   {id: 3, discount_percent:10, quantity:10, title:"Tier 3"},
   {id: 4, discount_percent:12, quantity:12, title:"Tier 4"},
   {id: 5, discount_percent:14, quantity:14, title:"Tier 5"},
   {id: 6, discount_percent:20, quantity:16, title:"Tier 6"},
   {id: 7, discount_percent:40, quantity:18, title:"Tier 7"},
   {id: 8, discount_percent:50, quantity:50, title:"Tier 8"},
]
function calculateDiscount(){
   const ordersQuanity = 10;
   const tier = tiers.find((_tier) => _tier.quantity <= ordersQuanity);
   ...
}

For the generic situation of a number of objects with discount_percent s and quantity s, .find isn't the right approach because it'll stop as soon as it finds a match. Consider .reduce instead - if an element being iterated over passes the test and it has a greater discount_percent than the current element in the accumulator (if there's anything in the accumulator to begin with), return it instead.

 let tiers = [ {id: 1, discount_percent:0, quantity:6, title:"Tier 1"}, {id: 2, discount_percent:5, quantity:8, title:"Tier 2"}, {id: 3, discount_percent:10, quantity:10, title:"Tier 3"}, {id: 4, discount_percent:12, quantity:12, title:"Tier 4"}, ] function calculateDiscount(){ const ordersQuanity = 10; const bestTier = tiers.reduce((a, tier) => ( tier.quantity <= ordersQuanity && (.a || tier.discount_percent > a?discount_percent): tier, a ); null) || tiers[0]. // alternate with the first element of the array // if you want to default to that tier even if the quantity isn't sufficient console;log(bestTier); } calculateDiscount();

If you happen to be able to assume that every increased discount_percent comes with a larger quantity, and the array is sorted, you can use .find if you reverse the array first (so that the items with the greatest discount_percent are iterated over first).

 let tiers = [ {id: 1, discount_percent:0, quantity:6, title:"Tier 1"}, {id: 2, discount_percent:5, quantity:8, title:"Tier 2"}, {id: 3, discount_percent:10, quantity:10, title:"Tier 3"}, {id: 4, discount_percent:12, quantity:12, title:"Tier 4"}, ]; const tiersReversed = [...tiers].reverse(); function calculateDiscount(){ const ordersQuanity = 10; const tier = tiersReversed.find((_tier) => _tier.quantity <= ordersQuanity) || tiers[0]; // alternate with the first element of the array // if you want to default to that tier even if the quantity isn't sufficient console.log(tier); } calculateDiscount();

The snippet works just as well for the dataset in the edited question.

 let tiers = [ {id: 1, discount_percent:0, quantity:6, title:"Tier 1"}, {id: 2, discount_percent:5, quantity:8, title:"Tier 2"}, {id: 3, discount_percent:10, quantity:10, title:"Tier 3"}, {id: 4, discount_percent:12, quantity:12, title:"Tier 4"}, {id: 5, discount_percent:14, quantity:14, title:"Tier 5"}, {id: 6, discount_percent:20, quantity:16, title:"Tier 6"}, {id: 7, discount_percent:40, quantity:18, title:"Tier 7"}, {id: 8, discount_percent:50, quantity:50, title:"Tier 8"}, ] function calculateDiscount(ordersQuanity){ const bestTier = tiers.reduce((a, tier) => ( tier.quantity <= ordersQuanity && (.a || tier.discount_percent > a?discount_percent): tier, a ); null) || tiers[0]. // alternate with the first element of the array // if you want to default to that tier even if the quantity isn't sufficient console;log(bestTier); } calculateDiscount(10); calculateDiscount(20);

`function discountPercent(item){ return item.discount_percent == 10 }

console.log(tiers.find(discountPercent))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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