For loop with Javascript to get values - javascript

I have this variable named: var quantity.
This variable changes continuously. For example: quantity = 1, quantity = 26...
On the other hand I have an array of elements with prices according to the quantity of the product: var quantity_prices.
var quantity_prices = [
{
"quantity": 1,
"price_pvp": 7.96
}, {
"quantity": 5,
"price_pvp": 7.96
}, {
"quantity": 15,
"price_pvp": 6.97
}, {
"quantity": 25,
"price_pvp": 5.97
}
];
I want to make that if quantity is between quantities 1 and 5, 6 and 14, 15 and 24, the product has the right price.
Example:
if the quantity is 16, the price I want to take is: 5,95€.
I've thought about using a for loop but I don't know how to continue to make this work what I want to do:
for (var i = 0; i < this.quantity_prices.length; i++) { // if quantity is between 1 and 5
new_price = this.quantity_prices[i].price_pvp;
// elseif quantity is between 6 and 14
new_price = this.quantity_prices[i].price_pvp;
// elseif quantity is between 15 and 24
new_price = this.quantity_prices[i].price_pvp;
}

var quantity_prices = [
{
"quantity": 1,
"price_pvp": 7.96,
},
{
"quantity": 5,
"price_pvp": 7.96,
},
{
"quantity": 15,
"price_pvp": 6.97,
},
{
"quantity": 25,
"price_pvp": 5.97,
}
];
for(let i=0;i<quantity_prices.length;i++){
if(quantity_prices[i].quantity>0 && quantity_prices[i].quantity<5 )
{
//whatever the required output you want.
quantity_prices[i].new_price=quantity_prices[i].price_pvp;
}if(quantity_prices[i].quantity>6 && quantity_prices[i].quantity<14){
}
if(quantity_prices[i].quantity>15 && quantity_prices[i].quantity<24){
}
}
console.log(quantity_prices)

Here try it with this:
function check(){
this.quantity_prices.find(({price}) => {
if(price_pvp > 1 && price_pvp < 5){
// do something
}
if(price_pvp > 6 && price_pvp < 14){
// do something
}
if(price_pvp > 15 && price_pvp < 24){
// do something
}
}
}

You can group according to your req as per below code and then print the price.
var quantity_prices = [{
"quantity": 1,
"price_pvp": 7.96,
},
{
"quantity": 5,
"price_pvp": 7.96,
},
{
"quantity": 15,
"price_pvp": 6.97,
},
{
"quantity": 25,
"price_pvp": 5.97,
}
];
var group1_5 = quantity_prices.filter(q => q.quantity >= 1 && q.quantity <= 5);
console.log(group1_5);
//print your price
if (group1_5.length > 0) {
console.log(group1_5[0].price_pvp)
}
var group6_16 = quantity_prices.filter(q => q.quantity >= 6 && q.quantity <= 14);
console.log(group6_16);

You can search for the right quantity, then return the price for this amount.
I'm assuming that if the quantity is not found directly we'll return the next entry in the quantity / price table.
const quantity_prices = [ { "quantity": 1, "price_pvp": 7.96, }, { "quantity": 5, "price_pvp": 7.96, }, { "quantity": 15, "price_pvp": 6.97, }, { "quantity": 25, "price_pvp": 5.97, } ];
function getPrice(quantity, priceLookup) {
let entry = priceLookup.find((e,index) => e.quantity >= quantity || index === priceLookup.length-1);
return entry.price_pvp;
}
console.log("Price table:");
const quantities = [1,4,5,10,15,16,25,26,30];
for(let quantity of quantities ) {
console.log(`Price (${quantity }): €${getPrice(quantity, quantity_prices)}`);
}

Related

How group students with different scores in leveled groups

I need to create groups of students to work together, but i need to level the groups using his grades. So, i don't want only the good grades students in one hand and the bad grades on other. I want to mix them all using his grades to randomize that.
So, i have the name and the score for every student. I need 3 homework groups, so i calculated the score of all / 3. To know the value who every single group need.
Now it's the problem, i don't know how can i insert the students in this groups without be over the max value for one group and how guarantee every group with same number of students.
Until now, i make this:
var totalScore = 0;
for (var i = 0; i < students.length; i++) {
totalScore = totalScore + students[i].score;
}
var maxScoreForGroup = totalScore / 3;
console.log(maxScoreForGroup);
for (var o = 0 ; o < students.length; o++) {
if ((students[o].score + homeWork1[0].scoreTotal) < maxScoreForGroup) {
homeWork1[0].students.push(students[o].name);
homeWork1[0].scoreTotal = homeWork1[0].scoreTotal + students[o].score;
} else if ((students[o].score + homeWork2[0].scoreTotal) < maxScoreForGroup) {
homeWork2[0].students.push(students[o].name);
homeWork2[0].scoreTotal = homeWork2[0].scoreTotal + students[o].score;
} else {
homeWork3[0].students.push(students[o].name);
homeWork3[0].scoreTotal = homeWork3[0].scoreTotal + students[o].score;
}
}
But i'm getting in homeWork1 only 2 students with score 10 each, in homework2 only 2 students with score 10 and 7.5, and in homework 3 every other student.
How can i change this to get 3 groups with 3 students and every group with the same score total?
My array of students
var students = [
{
"name": "Charles",
"score": 10
},
{
"name": "Max",
"score": 10
},
{
"name": "Samuel",
"score": 10
},
{
"name": "Carl",
"score": 7.5
},
{
"name": "James",
"score": 7.5
},
{
"name": "Frank",
"score": 7.5
},
{
"name": "George",
"score": 5
},
{
"name": "Timothy",
"score": 5
},
{
"name": "Paul",
"score": 5
},
]
My output is
"[{"scoreTotal":20,"students":["Charles","Max"]}]"
"[{"scoreTotal":17.5,"students":["Samuel","Carl"]}]"
"[{"scoreTotal":30,"students":["James","Frank","George","Timothy","Paul"]}]"
I made this fiddle too
Here's another approach that might work for you.
We shuffle the students array, split into groups of n students (in this case 3), then get the total scores of each group.
If the groups have the same total score we add to our possibleGroups array.
You can change the number of attempts or just repeat to get different groupings.
const students = [ { "name": "Charles", "score": 10 }, { "name": "Max", "score": 10 }, { "name": "Samuel", "score": 10 }, { "name": "Carl", "score": 7.5 }, { "name": "James", "score": 7.5 }, { "name": "Frank", "score": 7.5 }, { "name": "George", "score": 5 }, { "name": "Timothy", "score": 5 }, { "name": "Paul", "score": 5 }, ]
function shuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
function getTotalScore(a) {
return a.reduce((total, student) => total + student.score, 0);
}
function allEqual(a) {
return (new Set(a).size) === 1;
}
function split(a, groupSize) {
return a.reduce((sums, x, idx) => {
if (idx % groupSize === 0) {
sums.push([]);
}
sums[sums.length - 1].push(x);
return sums;
}, [])
}
let attempts = 20;
let n = 3;
let possibleGroups = [];
for(let i = 0; i < attempts; i++) {
let groups = split(shuffle([...students]), n);
let scores = groups.map(getTotalScore);
if (allEqual(scores)) {
possibleGroups.push( { scoreTotal: scores[0], groups } );
}
}
console.log('Possible groupings:');
possibleGroups.forEach((group, idx) => {
console.log(`Grouping ${idx + 1}:`);
console.log(JSON.stringify(group, null, 2))
})
.as-console-wrapper { max-height: 100% !important; }

Remove Object if Key Value don't match Input Variable after calculating and comparing with input variables

I am trying to compare input variable key/values with data in Json file, there are 200+ orders in the file, for Order_number (66 in this case) need to calculate and compare the count of line items(6 in this case) along with the Quantity of items(7 in this case), if it doesn't match need to remove Object Refund along with its elements, else leave it as it is.
The variables from the sql query result to be compared against this sample would be :
Order_number 66
count of line items 6
Quantity of items 6
I got stuck at calculating it.
File Content:
{
"app_id": 111,
"fulfillments": [],
"line_items": [
{
"id": 376,
"quantity": 2
},
{
"id": 992,
"quantity": 1
},
{
"id": 929,
"quantity": 1
},
{
"id": 768,
"quantity": 1
},
{
"id": 929,
"quantity": 1
},
{
"id": 768,
"quantity": 1
}
],
"name": "#59",
"number": 6,
"order_number": 66,
"order_id": 999,
]
}
var derivedOrderNumber = getVariable("Trans_ID", "");
var derivedNumberOfLineItems = getVariable("Count_Of_Fulfillment", "");
var derivedTotalQuantityOfItems = getVariable("Total_Quantity", "");
var jsonOrderNumber = 0;
var jsonNumberOfLineItems = 0;
var jsonTotalQuantityOfItems = 0;
//Calculate Number of Line Items and Total Quantity for order_number
let output = arr.reduce((op,cur)=>{
if(op[cur['ORDER_NUMBER']]){
op[cur['LINE_ITEMS']]['jsonTotalQuantityOfItems']+=cur['QUANTITY'];
op[cur['LINE_ITEMS']]['jsonNumberOfLineItems']++;
} else {
op[cur['ORDER_NUMBER']] ={
'jsonNumberOfLineItems' : 1,
'jsonTotalQuantityOfItems' : cur['QUANTITY'],
}
}
return op;
},{})
console.log(output);
try this
let arrSum = 0;
data.line_items.forEach((element) => {
arrSum += element.quantity;
});
if (arrSum != data.number) delete data.refunds;

How can I sum values inside reduce with multi condition?

I want to sum up all of data base on two condition in side my reduce function.
Let's say I have data as following:
const data = [
{
"id": 1,
"option": BP,
"result": 'win',
"amount": 50
},
{
"id": 3,
"option": BP,
"result": 'win',
"amount": 20
},
{
"id": 5,
"option":VN,
"result": 'win',
"amount": 50
},
{
"id": 5,
"option":GB,
"result": 'loss',
"amount": 40
}
];
Here is my code:
data.reduce((newValueBetting, modelBetting) => {
if (
modelBetting.option === 'VN'
&& modelBetting.result === 'win'
) {
newValueBetting += modelBetting.amount;
}
return newValueBetting;
}, 0);
Regarding to this code. it will sum when my data is matches with condition. But, if I want to sum up option === 'BP' && result === 'win'. So, I don't want to write code again. Any idea? How can I make my reduce run only one time and get to this object:
{
TotalBPWin: 70,
TotalVN: 50,
TotalGBLoss: 40
}
While using reduce pass an object with all 3 key TotalBPWin, TotalVN, TotalGBLoss with initial value as 0. Then conditionally add them together.
const data = [{
id: 1,
option: "BP",
result: "win",
amount: 50,
},
{
id: 3,
option: "BP",
result: "win",
amount: 20,
},
{
id: 5,
option: "VN",
result: "win",
amount: 50,
},
{
id: 5,
option: "GB",
result: "loss",
amount: 40,
},
];
const accumulator = {
TotalBPWin: 0,
TotalVN: 0,
TotalGBLoss: 0,
};
const result = data.reduce((newValueBetting, { option, result, amount }) => {
if (option === "VN" && result === "win") {
newValueBetting["TotalVN"] += amount;
} else if (option === "BP" && result === "win") {
newValueBetting["TotalBPWin"] += amount;
} else if (option === "GB" && result === "loss") {
newValueBetting["TotalGBLoss"] += amount;
}
return newValueBetting;
}, accumulator);
console.log(result);
The idea is to use object in reduce rather than 0. The following is the simple implementation, you will probably need to refine the condition in the reduce for summation.
const data = [
{
"id": 1,
"option": 'BP',
"result": 'win',
"amount": 50
},
{
"id": 3,
"option": 'BP',
"result": 'win',
"amount": 20
},
{
"id": 5,
"option":'VN',
"result": 'win',
"amount": 50
},
{
"id": 5,
"option":'GB',
"result": 'loss',
"amount": 40
}
];
let result = {
'VN':0,
'GB':0,
'BP':0
};
data.reduce((acc,item) => {
result[item.option] += item.amount
return acc;
}, result);
console.log(result)
The following reduce will get you a sum of counts for each option. Importantly, if any option has zero wins, then there won't be an associated sum for it (See the log output).
const data = [{id:1,option:"BP",result:"win",amount:50},{id:3,option:"BP",result:"win",amount:20},{id:5,option:"VN",result:"win",amount:50},{id:5,option:"GB",result:"loss",amount:40}];
const result = data.reduce((all, el) => {
if (el.result === "win") {
all[el.option] = (all[el.option] || 0) + el.amount;
}
return all;
}, {});
console.log(result.BP);
console.log(result.VN);
console.log(result.GB);
You just need a simple loop for this and no need for if() conditionals
const data=[{id:1,option:"BP",result:"win",amount:50},{id:3,option:"BP",result:"win",amount:20},{id:5,option:"VN",result:"win",amount:50},{id:5,option:"GB",result:"loss",amount:40}];
const res= {};
data.forEach(o=>{
const k = 'Total' + o.option + o.result
res[k] = (res[k] || 0) + o.amount
});
console.log(res)

How to optimize array grouping?

I have an array that is constantly updated and accordingly it is necessary to update its grouping. Example of an array:
[
{
"price": 2419.62,
"amount": 0.0266
},
{
"price": 1927.52,
"amount": 0.0217
},
...
]
I tried different options. At the moment this option is the fastest:
const points = [
{
"price": 2419.62,
"amount": 0.0266
},
{
"price": 1927.52,
"amount": 0.0217
},
...
];
const range = 500;
const spread = 1800;
const countGroup = 250;
const sizeUnitGroup = range / countGroup;
const groups = {};
for (let i = 0; i < countGroup; i++){
groups[i] = [];
try {
points.forEach((item, id) => {
if (item.price > spread + (i*sizeUnitGroup) && item.price <= spread + (i*sizeUnitGroup + sizeUnitGroup)){
groups[i].push(item);
points.splice(id, 1);
}
if (item.price > (spread + (i*sizeUnitGroup + sizeUnitGroup))) throw BreakException;
});
} catch (e) {
}
}
But even so, this function works for too long. Any ideas how this can be optimized?
You could calculate the interval for pushing the value to the wanted slot.
var points = [
{ price: 2419.62, amount: 0.0266 },
{ price: 1927.52, amount: 0.0217 },
{ price: 1800, amount: 0.07 }, // -1 not in result
{ price: 1800.000000000001, amount: 0.07 }, // 0
{ price: 1802, amount: 0.07 }, // 0
],
range = 500,
spread = 1800,
countGroup = 250,
sizeUnitGroup = range / countGroup,
groups = {};
points.forEach((item, id) => {
var i = Math.ceil((item.price - spread- sizeUnitGroup) / sizeUnitGroup);
if (i >= 0 && i < countGroup) {
groups[i] = groups[i] || [];
groups[i].push(item);
}
});
console.log(groups);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Pushing non existent items to array

So I have this array:
var period = [{"total":852, "date":"2016-03"}, {"total":963, "date":"2016-03"},{"total":789,"date":"2016-02"},{"total":456,"date":"2016-04"},{"total":123,"date":"2016-01"},{"total":723,"date":"2016-01"}];
I need to display "total" data grouped by month. Which means I have to sum "total" amount on months that are repeated on the array (2016-03, 2016-01). To find the solution I need to understand why this
for ( var i = 0; i < period.length; i++ ){
if (periodB.indexOf(period[i].date) == -1){
periodB.push(period[i].date);
}
Returns this:
["2016-03", "2016-02", "2016-04", "2016-01"]
While this:
for ( var i = 0; i < period.length; i++ ){
if (periodB.indexOf(period[i].date) == -1){
periodB.push({"date": period[i].date, "total": period[i].total});
}
}
Is returning this:
[{date: "2016-03",total: 1704}, {date: "2016-03", total: 1926}, {date:"2016-02", total: 1578},{date: "2016-04",total: 912}, {date: "2016-01",total: 246}, {date: "2016-01", total: 1446 }]
On the first case repeated "dates" are not being pushed on to periodB array, but then on the second case they are.
You can solve your task using temporary object and one forEach loop
var obj = {};
period.forEach(e => {
var month = e.date.split('-')[1]
obj[month] = obj[month] + e.total || e.total
});
Result will be an object with month as key and total sum as a value
{
'03': 1815,
'02': 789,
'04': 456,
'01': 846
}
Working example:
var period = [{ "total": 852, "date": "2016-03" }, { "total": 963, "date": "2016-03" }, { "total": 789, "date": "2016-02" }, { "total": 456, "date": "2016-04" }, { "total": 123, "date": "2016-01" }, { "total": 723, "date": "2016-01" }];
var obj = {};
period.forEach(e => {
var month = e.date.split('-')[1]
obj[month] = obj[month] + e.total || e.total
});
document.write(JSON.stringify(obj, 0, 2));

Categories