const bankAccounts = [
{
id: 1,
name: "Susan",
balance: 100.32,
deposits: [150, 30, 221],
withdrawals: [110, 70.68, 120],
},
{ id: 2, name: "Morgan", balance: 1100.0, deposits: [1100] },
{
id: 3,
name: "Joshua",
balance: 18456.57,
deposits: [4000, 5000, 6000, 9200, 256.57],
withdrawals: [1500, 1400, 1500, 1500],
},
{ id: 4, name: "Candy", balance: 0.0 },
{ id: 5, name: "Phil", balance: 18, deposits: [100, 18], withdrawals: [100] },
];
function getAllWithdrawals(bankAccounts) {
let newArr = [];
for (let acc of bankAccounts) {
if (acc.withdrawals) {
newArr.push(acc.withdrawals)
} else if (!acc.withdrawals) {
newArr.push(0);
}
}
return newArr;
}
I am getting access to the array objects. But how do I get into the objects with the array of withdrawals with varying amounts, add them all and print that in the blank array "newArr"? Do I need another for loop? My overall goal is to iterate through the objects check which ones pass that have withdrawals array. If they do not have a withdrawals array I pass 0. The objects that do have withdrawals I need to iterate through those and add them up and push the total of the withdrawal array into the "newArr".
Here is a functional programming solution that uses map reduce:
const bankAccounts = [ { id: 1, name: "Susan", balance: 100.32, deposits: [150, 30, 221], withdrawals: [110, 70.68, 120], }, { id: 2, name: "Morgan", balance: 1100.0, deposits: [1100] }, { id: 3, name: "Joshua", balance: 18456.57, deposits: [4000, 5000, 6000, 9200, 256.57], withdrawals: [1500, 1400, 1500, 1500], }, { id: 4, name: "Candy", balance: 0.0 }, { id: 5, name: "Phil", balance: 18, deposits: [100, 18], withdrawals: [100] }, ];
function getAllWithdrawals(bankAccounts) {
return bankAccounts.map(obj => {
return obj.withdrawals ? obj.withdrawals.reduce((sum, num) => sum + num, 0) : 0;
});
}
console.log(getAllWithdrawals(bankAccounts));
Output:
[
300.68,
0,
5900,
0,
100
]
Docs:
Intro to map reduce: https://medium.com/poka-techblog/simplify-your-javascript-use-map-reduce-and-filter-bd02c593cc2d
.map(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
.reduce(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reduce
Here is an enhanced version where you pass the deposits or withdrawls key into the function:
const bankAccounts = [ { id: 1, name: "Susan", balance: 100.32, deposits: [150, 30, 221], withdrawals: [110, 70.68, 120], }, { id: 2, name: "Morgan", balance: 1100.0, deposits: [1100] }, { id: 3, name: "Joshua", balance: 18456.57, deposits: [4000, 5000, 6000, 9200, 256.57], withdrawals: [1500, 1400, 1500, 1500], }, { id: 4, name: "Candy", balance: 0.0 }, { id: 5, name: "Phil", balance: 18, deposits: [100, 18], withdrawals: [100] }, ];
function getSums(bankAccounts, key) {
return bankAccounts.map(obj => {
return obj[key] ? obj[key].reduce((sum, num) => sum + num, 0) : 0;
});
}
console.log({
deposits: getSums(bankAccounts, 'deposits'),
withdrawals: getSums(bankAccounts, 'withdrawals'),
});
Output:
{
"deposits": [
401,
1100,
24456.57,
0,
118
],
"withdrawals": [
300.68,
0,
5900,
0,
100
]
}
UPDATE 1: Based on request to use only for loops:
const bankAccounts = [ { id: 1, name: "Susan", balance: 100.32, deposits: [150, 30, 221], withdrawals: [110, 70.68, 120], }, { id: 2, name: "Morgan", balance: 1100.0, deposits: [1100] }, { id: 3, name: "Joshua", balance: 18456.57, deposits: [4000, 5000, 6000, 9200, 256.57], withdrawals: [1500, 1400, 1500, 1500], }, { id: 4, name: "Candy", balance: 0.0 }, { id: 5, name: "Phil", balance: 18, deposits: [100, 18], withdrawals: [100] }, ];
function getAllWithdrawals(bankAccounts) {
let result = [];
for (let obj of bankAccounts) {
let sum = 0;
if(obj.withdrawals) {
for (num of obj.withdrawals) {
sum += num;
}
}
result.push(sum);
}
return result;
}
console.log(getAllWithdrawals(bankAccounts));
Not sure if I understood your question, but if u have to sum ALL of the withdrawals you should do it in this way:
const bankAccounts = [
{
id: 1,
name: "Susan",
balance: 100.32,
deposits: [150, 30, 221],
withdrawals: [110, 70.68, 120],
},
{ id: 2, name: "Morgan", balance: 1100.0, deposits: [1100] },
{
id: 3,
name: "Joshua",
balance: 18456.57,
deposits: [4000, 5000, 6000, 9200, 256.57],
withdrawals: [1500, 1400, 1500, 1500],
},
{ id: 4, name: "Candy", balance: 0.0 },
{ id: 5, name: "Phil", balance: 18, deposits: [100, 18], withdrawals: [100] },
];
function getAllWithdrawals(bankAccounts) {
let newArr = [];
for (let acc of bankAccounts) {
if (!!acc.withdrawals) {
acc.withdrawals.forEach(withdrawal => newArr.push(withdrawal))
}
}
return newArr.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
}
console.log(getAllWithdrawals(bankAccounts))
Otherwise if you have to sum the withdrawals of the single object you have to use this code:
const bankAccounts = [
{
id: 1,
name: "Susan",
balance: 100.32,
deposits: [150, 30, 221],
withdrawals: [110, 70.68, 120],
},
{ id: 2, name: "Morgan", balance: 1100.0, deposits: [1100] },
{
id: 3,
name: "Joshua",
balance: 18456.57,
deposits: [4000, 5000, 6000, 9200, 256.57],
withdrawals: [1500, 1400, 1500, 1500],
},
{ id: 4, name: "Candy", balance: 0.0 },
{ id: 5, name: "Phil", balance: 18, deposits: [100, 18], withdrawals: [100] },
];
function getAllWithdrawals(bankAccounts) {
let newArr = [];
for (let acc of bankAccounts) {
if (!!acc.withdrawals) {
newArr.push(acc.withdrawals.reduce((accumulator, currentValue) => accumulator + currentValue, 0))
}
}
return newArr;
}
console.log(getAllWithdrawals(bankAccounts))
Related
I have a JSON array containing several objects. I would like to return objects containing a certain value. For example, I would like to return
[
service_wog: {
count: 48,
popular: false,
code: 33,
price: 20,
id: 76,
service: 'WOG',
slug: 'wog'
},
service_gojoy: {
count: 48,
popular: false,
code: 33,
price: 20,
id: 77,
service: 'GoJoy',
slug: 'gojoy'
}
]
How do I return the object that contains 'gojoy' in slug?
I tried the following way:
let u = Object.values(a);
u.filter(i => i.slug === 'gojoy');
It doesn't seem to be working... Did I misunderstand how the filter() works?
No, it seems that you're using filter correctly.
However, what are you using as an input:
[
service_wog: {
count: 48,
popular: false,
code: 33,
price: 20,
id: 76,
service: 'WOG',
slug: 'wog'
},
service_gojoy: {
count: 48,
popular: false,
code: 33,
price: 20,
id: 77,
service: 'GoJoy',
slug: 'gojoy'
}
]
it's not a valid array, but an object.
So instead of [ and ] - { and } should be used:
{
service_wog: {
count: 48,
popular: false,
code: 33,
price: 20,
id: 76,
service: 'WOG',
slug: 'wog'
},
service_gojoy: {
count: 48,
popular: false,
code: 33,
price: 20,
id: 77,
service: 'GoJoy',
slug: 'gojoy'
}
}
So eventually:
const a = {
service_wog: {
count: 48,
popular: false,
code: 33,
price: 20,
id: 76,
service: 'WOG',
slug: 'wog'
},
service_gojoy: {
count: 48,
popular: false,
code: 33,
price: 20,
id: 77,
service: 'GoJoy',
slug: 'gojoy'
}
}
let u = Object.values(a);
console.log(u.filter(i => i.slug === 'gojoy'));
I want to merge two arrays of objects. One key will be the same in those 2 arrays.
Here is the sample data:
var a = ['Europe', 'Africa', 'Antarctica'];
var b = [
{id: 11, warehouse_name: 'Europe', input_qty: 200, total_amt: 4000},
{id: 12, warehouse_name: 'Africa', input_qty: 150, total_amt: 3500},
{id: 13, warehouse_name: 'Africa', input_qty: 20, total_amt: 500},
{id: 14, warehouse_name: 'Antarctica', input_qty: 50, total_amt: 1500}
];
My expected output should be:
var c = [
{warehouse_name: 'Europe', pack: [{id: 11, warehouse_name: 'Europe', input_qty: 200, total_amt: 4000}]},
{warehouse_name: 'Africa', pack: [{id: 12, warehouse_name: 'Africa', input_qty: 150, total_amt: 3500}, {id: 13, warehouse_name: 'Africa', input_qty: 20, total_amt: 500}]},
{warehouse: 'Antarctica', pack: [{id: 14, warehouse_name: 'Antarctica', input_qty: 50, total_amt: 1500}]}
];
How can i achieve this in javascript using lodash or without using lodash. Any solution is appreciated.
You could do it using array Array.prototype.map() method. Traverse the a array using map and filter b array by a arrays value using Array.prototype.filter method.
const a = ['Europe', 'Africa', 'Antarctica'];
const b = [
{ id: 11, warehouse_name: 'Europe', input_qty: 200, total_amt: 4000 },
{ id: 12, warehouse_name: 'Africa', input_qty: 150, total_amt: 3500 },
{ id: 13, warehouse_name: 'Africa', input_qty: 20, total_amt: 500 },
{ id: 14, warehouse_name: 'Antarctica', input_qty: 50, total_amt: 1500 },
];
const ret = a.map((x) => ({
warehouse_name: x,
pack: b.filter((y) => y.warehouse_name === x),
}));
console.log(ret);
Use _.groupBy() create an object (byWarehouse) of items by warehouse_name from array b. Now map array a, and take the items from byWarehouse to create the object:
const a = ['Europe', 'Africa', 'Antarctica'];
const b = [
{ id: 11, warehouse_name: 'Europe', input_qty: 200, total_amt: 4000 },
{ id: 12, warehouse_name: 'Africa', input_qty: 150, total_amt: 3500 },
{ id: 13, warehouse_name: 'Africa', input_qty: 20, total_amt: 500 },
{ id: 14, warehouse_name: 'Antarctica', input_qty: 50, total_amt: 1500 },
];
const byWarehouse = _.groupBy(b, 'warehouse_name')
const result = a.map(warehouse_name => ({ warehouse_name, pack: byWarehouse[warehouse_name] }))
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>
I'm doing some calculations of the total cost of items in an array that would be displayed in the HTML, the total sum should be such that when making the calculations, it should consider the discount amount against each row and add up together before it sums up all the rows total to make the total sum.
data
costItems = [
{
name: 'Corn Flakes'
unitPrice: 9,
quantity: 10,
hasDiscount: false,
discountPercentage: 10
},
{
name: 'Sugar'
unitPrice: 5,
quantity: 10,
hasDiscount: true,
discountPercentage: 10
},
{
name: 'Bread'
unitPrice: 2,
quantity: 7,
hasDiscount: false,
discountPercentage: 0
},
{
name: 'Salt'
unitPrice: 1,
quantity: 4,
hasDiscount: false,
discountPercentage: 0
}
]
Current Code I have
calculateTotalSum() {
this.totalSum = this.costItems.reduce((sum, {unitPrice, quantity}) => sum += unitPrice * quantity, 0);
console.log(this.totalSum)
}
This works by calculating the total sum ignoring the discount amounts but what I want to do is to consider the discounts in there
const costItems = [
{
name: 'Corn Flakes',
unitPrice: 9,
quantity: 10,
hasDiscount: false,
discountPercentage: 10,
},
{
name: 'Sugar',
unitPrice: 5,
quantity: 10,
hasDiscount: true,
discountPercentage: 10,
},
{
name: 'Bread',
unitPrice: 2,
quantity: 7,
hasDiscount: false,
discountPercentage: 0,
},
{
name: 'Salt',
unitPrice: 1,
quantity: 4,
hasDiscount: false,
discountPercentage: 0,
},
];
const totalSum = costItems.reduce(
(sum, { unitPrice, quantity, discountPercentage }) =>
(sum += unitPrice * quantity * (1 - discountPercentage / 100)),
0,
);
console.log(totalSum);
You can use Array.prototype.reduce.
let costItems = [{
name: 'Corn Flakes',
unitPrice: 9,
quantity: 10,
hasDiscount: false,
discountPercentage: 10
},
{
name: 'Sugar',
unitPrice: 5,
quantity: 10,
hasDiscount: true,
discountPercentage: 10
},
{
name: 'Bread',
unitPrice: 2,
quantity: 7,
hasDiscount: false,
discountPercentage: 0
},
{
name: 'Salt',
unitPrice: 1,
quantity: 4,
hasDiscount: false,
discountPercentage: 0
}
];
let sum = costItems.reduce((acc, val) => acc += (val.quantity * val.unitPrice) * ((100 - val.discountPercentage) / 100), 0);
console.log(sum)
I am trying to filter a form object and match against an array of 'Package' objects and return the name of the array of the best matched object.
var personA = {
name: "Budi",
age: 35,
occupation: "Engineer",
noRooms: 5,
minIncome: 35000,
maxIncome: 60000,
minBudgetPMth: 450,
maxBudgetPMth: 450,
minSqft: 900,
maxSqft: 900
}
And find match from this array against object keys.
var affordableHDB = [
{
name: "5-room",
minSqft: 860,
maxSqft: 1100,
noRooms: 5,
minIncome: 45000,
maxIncome: 10000,
minBudgetPMth: 400,
maxBudgetPMth: 700
},
{
name: "4-room",
minSqft: 430,
maxSqft: 910,
noRooms: 4,
minIncome: 30000,
maxIncome: 75000,
minBudgetPMth: 400,
maxBudgetPMth: 700
},
{
name: "3-room",
minSqft: 320,
maxSqft: 710,
noRooms: 3,
minIncome: 18000,
maxIncome: 42000,
minBudgetPMth: 200,
maxBudgetPMth: 450
},
{
name: "2-room",
minSqft: 270,
maxSqft: 330,
noRooms: 2,
minIncome: 15000,
maxIncome: 28000,
minBudgetPMth: 150,
maxBudgetPMth: 260
}
];
A function should should accept the form data (person object) and this array (affordableHDB) and return the top two best matched array name. E.g. 'Room-5', 'Room-4'. Thanks a lot!
You could use constaints and a rating scheme, like count all constraints, who are true and use it as score. Later sort the result and take the top count, you need.
var person = { name: "Budi", age: 35, occupation: "Engineer", noRooms: 5, minIncome: 35000, maxIncome: 60000, minBudgetPMth: 450, maxBudgetPMth: 450, minSqft: 900, maxSqft: 900 },
affordableHDB = [{ name: "5-room", minSqft: 860, maxSqft: 1100, noRooms: 5, minIncome: 45000, maxIncome: 10000, minBudgetPMth: 400, maxBudgetPMth: 700 }, { name: "4-room", minSqft: 430, maxSqft: 910, noRooms: 4, minIncome: 30000, maxIncome: 75000, minBudgetPMth: 400, maxBudgetPMth: 700 }, { name: "3-room", minSqft: 320, maxSqft: 710, noRooms: 3, minIncome: 18000, maxIncome: 42000, minBudgetPMth: 200, maxBudgetPMth: 450 }, { name: "2-room", minSqft: 270, maxSqft: 330, noRooms: 2, minIncome: 15000, maxIncome: 28000, minBudgetPMth: 150, maxBudgetPMth: 260 }],
scores = affordableHDB.map(function (a) {
var score = 0,
constraints = [
{ keys: ['noRooms'], fn: function (p, f) { return p === f; } },
{ keys: ['minSqft', 'minIncome', 'minBudgetPMth'], fn: function (p, f) { return p >= f; } },
{ keys: ['maxSqft', 'maxIncome', 'maxBudgetPMth'], fn: function (p, f) { return p <= f; } }
];
constraints.forEach(function (c) {
c.keys.forEach(function (k) {
score += c.fn(person[k], a[k]);
});
});
return { score: score, name: a.name };
});
scores.sort(function (a, b) { return b.score - a.score; });
console.log(scores.slice(0, 2).map(function (a) { return a.name; }));
console.log(scores);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have this data where I don't have control to format or do any changes
//input json data
[
{
"Breaks":[
{"points":12,"points_total":12,"average":8.0,"faults":[]},
{"points":17,"points_total":29,"average":11.6,"faults":[]},
{"points":6,"points_total":35,"average":11.6667,"faults":[]},
{"points":8,"points_total":43,"average":10.75,"faults":[]},
{"points":14,"points_total":57,"average":11.4,"faults":[]},
],
"team_name":"King Sports"
},
{
"Breaks":[
{"points":18,"points_total":18,"average":15.4286,"faults":[]},
{"points":2,"points_total":20,"average":10.0,"faults":[]},
{"points":7,"points_total":27,"average":9.0,"faults":[]},
{"points":9,"points_total":36,"average":9.0,"faults":[]},
{"points":4,"points_total":40,"average":8.0,"faults":[]},
{"points":4,"points_total":44,"average":7.33333,"faults":[]},
{"points":4,"points_total":48,"average":6.85714,"faults":[]},
{"points":8,"points_total":56,"average":7.0,"faults":[]},
{"points":1,"points_total":57,"average":6.33333,"faults":[]},
{"points":6,"points_total":63,"average":6.3,"faults":[]},
{"points":3,"points_total":66,"average":5.82353,"faults":[]},
{"points":6,"points_total":72,"average":6.0,"faults":[]},
{"points":7,"points_total":79,"average":6.07692,"faults":[]},
{"points":3,"points_total":82,"average":5.85714,"faults":[]},
{"points":0,"points_total":82,"average":5.65517,"faults":[]}
],
"team_name":"Lion Sports"
}
]
So, I need to rebuild/restructure it to get following result.
There will be 20 "Breaks" if no value found in "Breaks" till it reaches to 20 then it should have "null" values.
//the result what i wanted = output expected
[
['Breaks', 'King Sports', 'Lion Sports'],
['1', 12, 18],
['2', 29, 20],
['3', 35, 27],
['4', 43, 36],
['5', 57, 40],
['6', null, 44],
['7', null, 48],
['8', null, 56],
['9', null, 57],
['10', null, 63],
['11', null, 66],
['12', null, 72],
['13', null, 79],
['14', null, 82],
['15', null, null],
['16', null, null],
['17', null, null],
['18', null, null],
['19', null, null],
['20', null, null]
]
You could generate the result array first and the put the values in.
var data = [{ Breaks: [{ points: 12, points_total: 12, average: 8.0, faults: [] }, { points: 17, points_total: 29, average: 11.6, faults: [] }, { points: 6, points_total: 35, average: 11.6667, faults: [] }, { points: 8, points_total: 43, average: 10.75, faults: [] }, { points: 14, points_total: 57, average: 11.4, faults: [] }], team_name: "King Sports" }, { Breaks: [{ points: 18, points_total: 18, average: 15.4286, faults: [] }, { points: 2, points_total: 20, average: 10.0, faults: [] }, { points: 7, points_total: 27, average: 9.0, faults: [] }, { points: 9, points_total: 36, average: 9.0, faults: [] }, { points: 4, points_total: 40, average: 8.0, faults: [] }, { points: 4, points_total: 44, average: 7.33333, faults: [] }, { points: 4, points_total: 48, average: 6.85714, faults: [] }, { points: 8, points_total: 56, average: 7.0, faults: [] }, { points: 1, points_total: 57, average: 6.33333, faults: [] }, { points: 6, points_total: 63, average: 6.3, faults: [] }, { points: 3, points_total: 66, average: 5.82353, faults: [] }, { points: 6, points_total: 72, average: 6.0, faults: [] }, { points: 7, points_total: 79, average: 6.07692, faults: [] }, { points: 3, points_total: 82, average: 5.85714, faults: [] }, { points: 0, points_total: 82, average: 5.65517, faults: [] }], team_name: "Lion Sports" }],
result = data.reduce(function (r, a, i) {
r[0][i + 1] = a.team_name;
a.Breaks.forEach(function (b, j) {
r[j + 1][i + 1] = b.points_total;
});
return r;
}, function (length) {
var a = Array.apply(null, { length: length + 1 }).map(function (_, i) { return [(i || 'Breaks').toString(), null, null] });
return a;
}(20));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }