How to sum multiplication values from objects in an array? - javascript

if i have an array that looks like this :
"orderItems": [
{
"description": "Test",
"identifier": "Test identifier",
"priceCent": 1,
"lengthIn": 10,
"widthIn": 5,
"heightIn": 10,
"weightLbs": 3,
"quantity": 2
},
{
"description": "Test-2",
"identifier": "Test identifier",
"priceCent": 1,
"lengthIn": 10,
"widthIn": 5,
"heightIn": 10,
"weightLbs": 4,
"quantity": 3
}
]
How can I multiply weightLbs and quantity and sum those within the objects?
For example:
3 * 2 = 6
4 * 3 = 12
and result total I want is = 18
This is what I have so far, but this only adds weightLbs
return delivery.order.orderItems.reduce((prev, curr) => {
return prev + (curr.totalWeightLbs || 0);
}, 0);

orderItems.reduce((sum, currentItem) => {
return sum + (currentItem.weightLbs * currentItem.quantity);
}, 0);
this will multiply the values and sum them in the reduce accumulator

const dummyArray = [
{
"description": "Test",
"identifier": "Test identifier",
"priceCent": 1,
"lengthIn": 10,
"widthIn": 5,
"heightIn": 10,
"weightLbs": 3,
"quantity": 2
},
{
"description": "Test-2",
"identifier": "Test identifier",
"priceCent": 1,
"lengthIn": 10,
"widthIn": 5,
"heightIn": 10,
"weightLbs": 4,
"quantity": 3
}
];
let sum = 0;
for( i = 0; i < dummyArray.length; i++)
sum += dummyArray[i].weightLbs * dummyArray[i].quantity
console.log(sum)
this might work

Related

How can I randomize a single value in JavaScript object using Node.js

How can I randomize the values of these objects?
And can you assign it randomly every 10-20 minutes?
const fs = require('fs');
var winrate = Math.floor(Math.random() * 101);
// create a JSON object
const gamesg = [{
"ID": 1,
"GAME_CAMPS": "SG",
"GAMENAME": "FISHING GOD",
"IMG_PATH": "./SG/1 FISHING GOD.png",
"GAME_IMG": "1 FISHING GOD.png",
"WINRATE": winrate
},......................................{
"ID": 55,
"GAME_CAMPS": "SG",
"GAMENAME": "HONEY HUNTER",
"IMG_PATH": "./SG/55 HONEY HUNTER.png",
"GAME_IMG": "55 HONEY HUNTER.png",
"WINRATE": winrate
}
];
Here is a solution for creating a random value and to place that value into a JavaScript object:
const gamesg = [{
"WINRATE": 0
}, {
"ID": 1,
"WINRATE": 0
}, {
"ID": 2,
"WINRATE": 0
}, {
"ID": 3,
"WINRATE": 0
}, {
"ID": 4,
"WINRATE": 0
}];
let output = gamesg
.map(g => { g.WINRATE = Math.floor(Math.random() * 101); return g});
console.log(output);

How to find data in for every day of week in mongoose node js

Query
const weekGraph = await tmUserSubscriptions.aggregate([
{
$match:{$and:[{subscriptionId: mongoose.Types.ObjectId(subscriptionId)},
{createdAt:{$gte:moment().startOf('isoweek').toDate(),
$lt:moment().endOf('isoweek').toDate()}}
]}
},
{"$project":{
"_id:":1,
"createdAt":{"$dayOfWeek":"$createdAt"},
"subscriptionId":1,
}},
{"$group":{
"_id":"$createdAt",
"count":{$sum:1},
}}
])
Result i get
"data": [
{
"_id": 7,
"count": 1
},
{
"_id": 5,
"count": 2
},
{
"_id": 6,
"count": 1
}
]
expected Result
"data": [
{
"_id": 7,
"count": 1
},
{
"_id": 6,
"count": 2
},
{
"_id": 5,
"count": 1
},
{
"_id": 4,
"count": 0
},{
"_id": 3,
"count": 0
},{
"_id": 2,
"count": 0
}{
"_id": 1,
"count": 0
}
]
So here i want to achieve all data of current week day by day, in my current query if there is no data any of week day then it will not return that day, but as per my expected result i want all day of week data, if there is no data for any of week day then it will return 0, so i want all 7 days data,
here _id is represent day of week
Mongoose/MongoDB will only return the aggregate if the key exists. Otherwise, it will not return you the data (less data to transfer through the connection is always faster). Therefore, you will need to provide your own defaults if the aggregate does not have data for you.
var results = [{ _id: 1, count: 1 }] // assumed from your response
var hasResult = []
for (var result of results) {
hasResult.push(result._id)
}
for (var i = 1; i <= 7; i++) {
if (!hasResult.includes(i)) {
results.push({ _id: i, count: 0 })
}
}
console.log(results)

Convert string value to variable reference in javascript

I have the following code where I'm attempting to reference the values of one JSON object with the variables of another:
const ch = {
"columns": {
"COL1": {
"position": 1,
"composites": ["VAR1", "VAR3"]
},
"COL2": {
"position": 3,
"composites": ["VAR2"]
},
"COL3": {
"position": 2,
"composites": ["VAR4"]
}
}
}
const dataset = [{
"VAR1": "alpha",
"VAR2": 2,
"VAR3": "1015",
"VAR4": "z",
},
{
"VAR1": "beta",
"VAR2": 701,
"VAR3": "1023",
"VAR4": "z"
}
]
for (let l = 0; l < dataset.length; l++) {
for (const {
position,
composites
} of Object.values(ch.columns).sort((a, b) => a.position - b.position)) {
console.log(position, composites[0], dataset[l].VAR1)
/* eval[dataset[l].composites[0]], this[dataset[l].composites[0]]*/
}
}
The program correctly orders the columns and I can refer both values from 'ch', but I would like to use the first composites value as a variable reference to the dataset. Having googled the question I followed a couple of recommendations to either use 'this' or 'eval', but neither work. Where am I going wrong?
Ideally, if I could get the commented out code working the log should look like the following:
1 VAR1 alpha alpha
2 VAR4 alpha z
3 VAR2 alpha 2
1 VAR1 beta beta
2 VAR4 beta z
3 VAR2 beta 701
Use dataset[l][composites[0]] to get the additional column. See Dynamically access object property using variable
const ch = {
"columns": {
"COL1": {
"position": 1,
"composites": ["VAR1", "VAR3"]
},
"COL2": {
"position": 3,
"composites": ["VAR2"]
},
"COL3": {
"position": 2,
"composites": ["VAR4"]
}
}
}
const dataset = [{
"VAR1": "alpha",
"VAR2": 2,
"VAR3": "1015",
"VAR4": "z",
},
{
"VAR1": "beta",
"VAR2": 701,
"VAR3": "1023",
"VAR4": "z"
}
]
for (let l = 0; l < dataset.length; l++) {
for (const {
position,
composites
} of Object.values(ch.columns).sort((a, b) => a.position - b.position)) {
console.log(position, composites[0], dataset[l].VAR1, dataset[l][composites[0]])
}
}

Find elements above and below given number in object

I have object like below
[
{
"value": 14,
"name": "vwap"
},
{
"value": 1,
"name": "yopen"
},
{
"value": 12,
"name": "open"
},
{
"value": 13,
"name": "s3"
},
{
"value": 9,
"name": "fr1"
},
{
"value": 10,
"name": "fr2"
}
]
If my input is 9 , I need output as 1,9 and 10,12,13
If my input is 13 , I need output 1,9,10,12,13 and 14
Output should be 2 seperate objects like { "value": 10, "name": "fr2" } ,Also output should be sorted.
I tried something like below , but it works only for array.
function getVal(array, val, dir) {
for (var i=0; i < array.length; i++) {
if (dir == true) {
if (array[i] > val){
return array[i-1] || 0;
}
} else {
if (array[i] >= val) {
return array[i];
}
}
}
}
You can use filter() and check if given number is less or greater than objects value and use sort() in end
const arr = [ { "value": 14, "name": "vwap" }, { "value": 1, "name": "yopen" }, { "value": 12, "name": "open" }, { "value": 13, "name": "s3" }, { "value": 9, "name": "fr1" }, { "value": 10, "name": "fr2" } ]
function getParts(arr,num,min=0,max=Infinity){
let first = arr.filter(x => num >= x.value && x.value > min && x.value < max).sort((a,b) => a.value-b.value);
let second = arr.filter(x => num < x.value && x.value < max && x.value > min).sort((a,b) => a.value-b.value);
return [first,second];
}
console.log(getParts(arr,9,5,12))
console.log('----------For 13--------------')
console.log(getParts(arr,13))
Another way is to sort() the array first and then slice() it.
const arr = [ { "value": 14, "name": "vwap" }, { "value": 1, "name": "yopen" }, { "value": 12, "name": "open" }, { "value": 13, "name": "s3" }, { "value": 9, "name": "fr1" }, { "value": 10, "name": "fr2" } ]
function getParts(arr,num){
let temp = arr.slice().sort((a,b) => a.value - b.value);
let index = temp.findIndex(x => x.value === num);
return [temp.slice(0,index+1),temp.slice(index)];
}
console.log(JSON.parse(JSON.stringify(getParts(arr,9))))
console.log('----------For 13--------------')
console.log(JSON.parse(JSON.stringify(getParts(arr,13))))
You could take acheck and push the object into the wanted array.
function getParts(value) {
return data.reduce((r, o) => (r[+(o.value > value)].push(o), r), [[], []]);
}
var data = [{ value: 14, name: "vwap" }, { value: 1, name: "yopen" }, { value: 12, name: "open" }, { value: 13, name: "s3" }, { value: 9, name: "fr1" }, { value: 10, name: "fr2" }];
data.sort(({ value: a }, { value: b }) => a - b);
console.log(getParts(9));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use an object to store your result, containing both lower and upper parts.
Then, loop your array and compare the value against the input. You'll know where to store your element, in lower or upper part
let datas = [{"value":14,"name":"vwap"},{"value":1,"name":"yopen"},{"value":12,"name":"open"},{"value":13,"name":"s3"},{"value":9,"name":"fr1"},{"value":10,"name":"fr2"}];
function getVal(input)
{
let result =
{
lowerPart: [],
upperPart: []
};
datas.forEach((elem) =>
{
if (elem.value <= input)
result.lowerPart.push(elem);
else
result.upperPart.push(elem);
});
return result;
}
console.log(getVal(9));
console.log(getVal(13));
Using reduce()
var arr = [{"value":14,"name":"vwap"},{"value":1,"name":"yopen"},{"value":12,"name":"open"},{"value":13,"name":"s3"},{"value":9,"name":"fr1"},{"value":10,"name":"fr2"}]
function getVal(arr, find) {
return arr.reduce((acc, i) => {
acc[i.value <= find ? 'l' : 'g'].push(i)
return acc
}, {
l: [],
g: []
})
}
console.log(getVal(arr, 9))
console.log(getVal(arr, 13))
.as-console-wrapper { max-height: 100% !important; top: 0; }
Usage
let res = getVal(arr, 9)
res.l // lowerpart
res.g // greaterpart
You can use filter and sort function for your requirement.
var find = 9;
var left = arr.filter(c=>c.value <= find).sort((a,b) => a.value-b.value);
var right = arr.filter(c=>c.value > find).sort((a,b) => a.value-b.value);
var arr = [
{
"value": 14,
"name": "vwap"
},
{
"value": 1,
"name": "yopen"
},
{
"value": 12,
"name": "open"
},
{
"value": 13,
"name": "s3"
},
{
"value": 9,
"name": "fr1"
},
{
"value": 10,
"name": "fr2"
}
]
var find = 9;
var left = arr.filter(c=>c.value <= find).sort((a,b) => a.value-b.value);
var right = arr.filter(c=>c.value > find).sort((a,b) => a.value-b.value);
console.log('Less than or equal: ' + find);
console.log(left)
console.log('Greater than: ' + find);
console.log(right)

map and reduce an array at the same time in javascript

I have an array of ~1800 object represents games played in a league. I need a new array that has an object for each team, and will include 4 new fields (wins, losses, ties, and points). Here is a sample of the array I am working with:
[
{
"homeGoals": 2,
"gameId": "12221",
"homeTeam": {
"id": "aasfdsf1",
"teamName": "Team 1"
},
"awayTeam": {
"id": "aasfdsf2",
"teamName": "Team 2"
},
"id": "ggaew1",
"awayGoals": 4
},
{
"homeGoals": 5,
"gameId": "12222",
"homeTeam": {
"id": "aasfdsf1",
"teamName": "Team 1"
},
"awayTeam": {
"id": "aasfdsf3",
"teamName": "Team 3"
},
"id": "ggaew2",
"awayGoals": 1
},
{
"homeGoals": 4,
"gameId": "12223",
"homeTeam": {
"id": "aasfdsf2",
"teamName": "Team 2"
},
"awayTeam": {
"id": "aasfdsf3",
"teamName": "Team 3"
},
"id": "ggaew3",
"awayGoals": 4
},
{
"homeGoals": null,
"gameId": "12223",
"homeTeam": {
"id": "aasfdsf2",
"teamName": "Team 2"
},
"awayTeam": {
"id": "aasfdsf3",
"teamName": "Team 3"
},
"id": "ggaew4",
"awayGoals": null
}
]
And here is an example of what I need the result to look like:
[
{
"id": "aasfdsf1",
"name": "Team 1",
"wins": 1,
"losses": 1,
"ties": 0,
"points": 2
},
{
"id": "aasfdsf2",
"name": "Team 2",
"wins": 1,
"losses": 0,
"ties": 1,
"points": 3
},
{
"id": "aasfdsf3",
"name": "Team 3",
"wins": 0,
"losses": 1,
"ties": 1,
"points": 1
}
]
Some games have not been played, so the homeGoals and awayGoals fields will be null.
So far I have a list of unique teams, only where the games have been completed:
const completedGames = games.filter(x => x.homeGoals !== null)
const homeTeams = [...new Set(completedGames.map(x => x['homeTeam']))];
const awayTeams = [...new Set(completedGames.map(x => x['awayTeam']))];
const teams = [...new Set([...homeTeams, ...awayTeams])]
I know I need to do some sort of reduce function, but am having trouble figuring it. I am pretty sure the step I just did before would be irrelevant if I had a proper map reduce function. Any help would be greatly appreciated !
This can be expressed in a simpler way with flatMap. It's not built-in in JS, but easy to implement:
let flatMap = (a, fn) => [].concat(...a.map(fn));
Now, on the map step, you can emit two "result" object per game (or no results at all if the game is incomplete):
results = flatMap(data, g => {
if (g.homeGoals === null || g.awayGoals === null)
return [];
if (g.homeGoals > g.awayGoals)
return [
{id: g.homeTeam.id, r: 'win'},
{id: g.awayTeam.id, r: 'loss'},
];
if (g.homeGoals < g.awayGoals)
return [
{id: g.homeTeam.id, r: 'loss'},
{id: g.awayTeam.id, r: 'win'},
];
if (g.homeGoals === g.awayGoals)
return [
{id: g.homeTeam.id, r: 'tie'},
{id: g.awayTeam.id, r: 'tie'},
];
});
This creates an array like
{ id: 'aasfdsf1', r: 'loss' },
{ id: 'aasfdsf2', r: 'win' },
{ id: 'aasfdsf1', r: 'win' }, etc
which is easy to reduce:
summary = results.reduce((m, {id, r}) => {
let e = m[id] || {};
e[r] = (e[r] || 0) + 1;
return Object.assign(m, {[id]: e})
}, {});
You can also make is less verbose by encoding wins, losses and ties by 1, -1, 0 respectively, in which case the mapper becomes:
results = flatMap(
data.filter(g => g.homeGoals !== null),
g => {
let d = g.homeGoals - g.awayGoals;
return [
{id: g.homeTeam.id, r: Math.sign(+d)},
{id: g.awayTeam.id, r: Math.sign(-d)},
]
});
I think you are looking to something like this:
const hashMapTeams = games.filter(x => x.homeGoals !== null)
.reduce((res, match)=>{
/* do the calculations here */
/* put the values on the res object, using res as a HashMap*/
res["/*the home team id*/"].id = /*id value*/
res["/*the home team id*/"].name = /*name value*/
res["/*the home team id*/"].wins= /* the right value */;
res["/*the home team id*/"].losses= /* the right value */;
res["/*the home team id*/"].ties= /* the right value */;
res["/*the home team id*/"].points= /* the right value */;
res["/*the away team id*/"].id = /*id value*/
res["/*the away team id*/"].name = /*name value*/
res["/*the away team id*/"].wins= /* the right value */;
res["/*the away team id*/"].losses= /* the right value */;
res["/*the away team id*/"].ties= /* the right value */;
res["/*the away team id*/"].points= /* the right value */;
},{});
/* This will convert again the object to an array */
const arrayTeams = Object.keys(hashMapTeams).map(function (key) { return hashMapTeams[key]; });
This gets the exactly result you are looking for:
{
"id": "aasfdsf1",
"name": "Team 1",
"wins": 1,
"losses": 1,
"ties": 0,
"points": 2
},
I used tenary and brackets to show you more than one way to approach that, you can use either one.
let result = [];
your1800ArrayObj.map(data => {
let wins = data.wins ? data.wins : 0;
let losses = data.losses ? data.losses : 0;
let ties = data['ties'] || 0;
let points = data['points'] || 0;
if (data.homeGoals === null && data.awayGoals === null) {
console.log('game not played')
} else {
if (data.homeGoals > data.awayGoals) {
wins += 1
points += 1
} else if (data.homeGoals < data.awayGoals) {
losses += 1
} else {
ties += 1
}
}
result.push({
id: data.id,
name: data.homeTeam.teamName ,
wins: wins,
losses: losses,
ties: ties,
points: points
})
})
return result
}

Categories

Resources