(14) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {itemId: 'F4', itemRate: 20, Amount: 20, itemName: 'Kesar pista', itemQuantity: 1}
1: {itemName: 'Vegetable manchuri', itemRate: 60, itemId: 'G5', Amount: 120, itemQuantity: 2}
2: {itemRate: 50, Amount: 50, itemQuantity: 1, itemId: 'C10', itemName: 'Dry fruit '}
3: {itemId: 'C3', itemRate: 40, itemQuantity: 1, Amount: 40, itemName: 'Butter scotch'}
4: {itemName: 'Panner sandwich + milk shake', Amount: 90, itemId: 'CS4', itemRate: 90, itemQuantity: 1}
5: {itemQuantity: 1, itemId: 'B5', itemRate: 70, Amount: 70, itemName: 'Panner burger'}
6: {itemId: 'C10', itemQuantity: 1, Amount: 50, itemName: 'Dry fruit ', itemRate: 50}
7: {itemQuantity: 2, itemName: 'American nuts', Amount: 100, itemRate: 50, itemId: 'C8'}
8: {itemName: 'Mango ', Amount: 50, itemQuantity: 1, itemId: 'C7', itemRate: 50}
9: {Amount: 40, itemId: 'C6', itemQuantity: 1, itemName: 'Choclate ', itemRate: 40}
10: {itemRate: 40, itemId: 'C3', itemQuantity: 1, Amount: 40, itemName: 'Butter scotch'}
11: {itemRate: 45, itemId: 'B1', itemName: 'Veg burger', Amount: 45, itemQuantity: 1}
12: {itemName: 'Veg cheese', Amount: 55, itemId: 'B2', itemQuantity: 1, itemRate: 55}
13: {itemName: 'Vanila', itemQuantity: 1, itemId: 'C1', Amount: 30, itemRate: 30}
length: 14
[[Prototype]]: Array(0)
I have a array. In the array there are 2 [id] values that are the same. I want to add the quantity,rate of these elements and merge the elements where the [id] are the same using javascript. I had tried following method but it shows wrong value.
let result = Object.values(this.orderDetail.reduce((c, {itemId,itemRate,itemQuantity,itemName}) => {
c[itemId] = c[itemId] || {itemId,itemRate,itemQuantity,itemName: 0};
c[itemId].itemRate += itemRate;
c[itemId].itemQuantity += itemQuantity;
c[itemId].itemName = itemName;
return c;
}, {}));
result
The issue is with the first line in the accumulator.
c[itemId] = c[itemId] || {itemId,itemRate,itemQuantity,itemName: 0};
You should assign the initial values here. This should be as below
c[itemId] = c[itemId] || { itemId, itemRate: 0, itemQuantity: 0, itemName: '', Amount: 0 };
Or else, you will be adding the first value twice to the accumulator.
Working Fiddle
const data = [{ itemId: 'F4', itemRate: 20, Amount: 20, itemName: 'Kesar pista', itemQuantity: 1 },
{ itemId: 'G5', itemName: 'Vegetable manchuri', itemRate: 60, Amount: 120, itemQuantity: 2 },
{ itemId: 'C10', itemRate: 50, Amount: 50, itemQuantity: 1, itemName: 'Dry fruit ' },
{ itemId: 'C3', itemRate: 40, itemQuantity: 1, Amount: 40, itemName: 'Butter scotch' },
{ itemId: 'CS4', itemName: 'Panner sandwich + milk shake', Amount: 90, itemRate: 90, itemQuantity: 1 },
{ itemId: 'B5', itemQuantity: 1, itemRate: 70, Amount: 70, itemName: 'Panner burger' },
{ itemId: 'C10', itemQuantity: 1, Amount: 50, itemName: 'Dry fruit ', itemRate: 50 },
{ itemId: 'C8', itemQuantity: 2, itemName: 'American nuts', Amount: 100, itemRate: 50 },
{ itemId: 'C7', itemName: 'Mango ', Amount: 50, itemQuantity: 1, itemRate: 50 },
{ itemId: 'C6', Amount: 40, itemQuantity: 1, itemName: 'Choclate ', itemRate: 40 },
{ itemId: 'C3', itemRate: 40, itemQuantity: 1, Amount: 40, itemName: 'Butter scotch' },
{ itemId: 'B1', itemRate: 45, itemName: 'Veg burger', Amount: 45, itemQuantity: 1 },
{ itemId: 'B2', itemName: 'Veg cheese', Amount: 55, itemQuantity: 1, itemRate: 55 },
{ itemId: 'C1', itemName: 'Vanila', itemQuantity: 1, Amount: 30, itemRate: 30 },
];
let result = Object.values(data.reduce((c, { itemId, itemRate, itemQuantity, itemName, Amount }) => {
const temp = { itemId, itemRate: 0, itemQuantity: 0, itemName: '', Amount: 0 };
c[itemId] = c[itemId] || temp;
c[itemId].itemRate += itemRate;
c[itemId].itemQuantity += itemQuantity;
c[itemId].itemName = itemName;
c[itemId].Amount += Amount;
return c;
}, {}));
console.log(result);
As I looked into the result, there is one extra time all values are passing into it. I guess you should try passing default values zero or an empty string to it.
Related
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))
I want it to be sorted by date and alphabet in one sort how can i do that ?
I think alphabetical order works good but date not works properly. Thanks for answers.
Data structure :
[{
productId: 21,
title: "Huawei P40 Lite ",
brand: "Huawei",
price: 120,
discountPercentage: 10,
color: "Black",
createdDate: "2021-01-15T01:00:00+03:00",
},
{
productId: 22,
title: "Huawei P40 Lite",
brand: "Huawei",
price: 1026,
discountPercentage: 0,
color: "Green",
createdDate: "2021-01-16T01:00:00+03:00",
},
{
productId: 23,
title: "Apple iPhone 11",
brand: "Apple",
price: 1220,
discountPercentage: 11,
color: "White",
createdDate: "2021-01-17T01:00:00+03:00",
},
{
productId: 24,
title: "Apple iPhone 12",
brand: "Apple",
price: 1420,
discountPercentage: 11,
color: "White",
createdDate: "2021-01-18T01:00:00+03:00",
}],
Here my work :
jsfiddle.net/pazyqb01/
And tried different solutions for sort date somehow i couldn't make it work.
Sorted Array shoul be like above :
{
productId: 24,
title: "Apple iPhone 12",
brand: "Apple",
price: 1420,
discountPercentage: 11,
color: "White",
createdDate: "2021-01-18T01:00:00+03:00",
},
{
productId: 23,
title: "Apple iPhone 11",
brand: "Apple",
price: 1220,
discountPercentage: 11,
color: "White",
createdDate: "2021-01-17T01:00:00+03:00",
},
{
productId: 22,
title: "Huawei P40 Lite",
brand: "Huawei",
price: 1026,
discountPercentage: 0,
color: "Green",
createdDate: "2021-01-16T01:00:00+03:00",
},
{
productId: 21,
title: "Huawei P40 Lite ",
brand: "Huawei",
price: 120,
discountPercentage: 10,
color: "Black",
createdDate: "2021-01-15T01:00:00+03:00",
},
this way:
simply follow the list of your sorting criteria
const data =
[ { productId: 21, title: 'Huawei P40 Lite ', brand: 'Huawei', price: 120, discountPercentage: 10, color: 'Black', createdDate: '2021-01-15T01:00:00+03:00' }
, { productId: 22, title: 'Huawei P40 Lite', brand: 'Huawei', price: 1026, discountPercentage: 0, color: 'Green', createdDate: '2021-01-16T01:00:00+03:00' }
, { productId: 23, title: 'Apple iPhone 11', brand: 'Apple', price: 1220, discountPercentage: 11, color: 'White', createdDate: '2021-01-17T01:00:00+03:00' }
, { productId: 24, title: 'Apple iPhone 12', brand: 'Apple', price: 1420, discountPercentage: 11, color: 'White', createdDate: '2021-01-18T01:00:00+03:00' }
]
const fSort = (a,b) =>
{
let Dx = new Date(b.createdDate) - new Date(a.createdDate) // 1st criteria
if (Dx===0) Dx = a.title.trim().localeCompare(b.title.trim()) // 2nd
// if (Dx===0) Dx = ... // 3rd
// if (Dx===0) Dx = ... // 4th....
return Dx
}
console.log( data.sort(fSort))
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 have a morris double line graph like this:
var lineGraph = Morris.Area({
element: 'graph_line',
xkey: 'Date',
ykeys: ['Sales', 'Revenue'],
labels: ['Sales','Revenue'],
fillOpacity: '0.7',
gridTextFamily: 'mtsRegular',
hideHover: 'auto',
lineWidth: '1px',
lineColors: ['#076178','#1ecee8'],
pointFillColors: ['#fff'],
pointStrokeColors: ['#012e42'],
data: [#Html.Raw(ViewBag.LineGraph)],
resize: true
});
And once the graph is rendered, it's missing the x and y axis labels... It looks like following:
What am I missing out here? Can someone help me out?
#Mohamed here is the content of ViewBag.LineGraph:
{ Date: '2018-08-06', Sales: 1, Revenue: 9.75 },
{ Date: '2018-08-08', Sales: 1, Revenue: 21.03 },
{ Date: '2018-08-09', Sales: 1, Revenue: 4.75 },
{ Date: '2018-08-12', Sales: 1, Revenue: 27.66 },
{ Date: '2018-08-13', Sales: 3, Revenue: 63.33 },
{ Date: '2018-08-16', Sales: 2, Revenue: 192.29 },
{ Date: '2018-08-18', Sales: 2, Revenue: 47.37 },
{ Date: '2018-08-19', Sales: 1, Revenue: 28.94 },
{ Date: '2018-08-20', Sales: 1, Revenue: 66.09 },
{ Date: '2018-08-21', Sales: 1, Revenue: 24.73 },
{ Date: '2018-08-22', Sales: 4, Revenue: 93.53 },
{ Date: '2018-08-23', Sales: 1, Revenue: 27.59 },
{ Date: '2018-08-25', Sales: 2, Revenue: 142.52 },
{ Date: '2018-08-26', Sales: 1, Revenue: 24.77 },
{ Date: '2018-08-27', Sales: 3, Revenue: 69.79 },
{ Date: '2018-08-29', Sales: 2, Revenue: 67.63 },
{ Date: '2018-08-30', Sales: 1, Revenue: 15.3 },
{ Date: '2018-09-01', Sales: 1, Revenue: 73.69 },
{ Date: '2018-09-02', Sales: 4, Revenue: 270.38 },
{ Date: '2018-09-03', Sales: 2, Revenue: 50.07 }
Working fine for me?
var lineGraph = Morris.Area({
element: 'graph_line',
xkey: 'Date',
ykeys: ['Sales', 'Revenue'],
labels: ['Sales','Revenue'],
fillOpacity: '0.7',
gridTextFamily: 'mtsRegular',
hideHover: 'auto',
lineWidth: '1px',
lineColors: ['#076178','#1ecee8'],
pointFillColors: ['#fff'],
pointStrokeColors: ['#012e42'],
data: [{ 'Date': '2018-08-06', Sales: 1, Revenue: 9.75},{ Date: '2018-08-08', Sales: 1, Revenue: 21.03},{ Date: '2018-08-09', Sales: 1, Revenue: 4.75},{ Date: '2018-08-12', Sales: 1, Revenue: 27.66},{ Date: '2018-08-13', Sales: 3, Revenue: 63.33},{ Date: '2018-08-16', Sales: 2, Revenue: 192.29},{ Date: '2018-08-18', Sales: 2, Revenue: 47.37},{ Date: '2018-08-19', Sales: 1, Revenue: 28.94},{ Date: '2018-08-20', Sales: 1, Revenue: 66.09},{ Date: '2018-08-21', Sales: 1, Revenue: 24.73},{ Date: '2018-08-22', Sales: 4, Revenue: 93.53},{ Date: '2018-08-23', Sales: 1, Revenue: 27.59},{ Date: '2018-08-25', Sales: 2, Revenue: 142.52},{ Date: '2018-08-26', Sales: 1, Revenue: 24.77},{ Date: '2018-08-27', Sales: 3, Revenue: 69.79},{ Date: '2018-08-29', Sales: 2, Revenue: 67.63},{ Date: '2018-08-30', Sales: 1, Revenue: 15.3},{ Date: '2018-09-01', Sales: 1, Revenue: 73.69},{ Date: '2018-09-02', Sales: 4, Revenue: 270.38},{ Date: '2018-09-03', Sales: 2, Revenue: 50.07}],
resize: true
});
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
<div id="graph_line" style="height: 250px;"></div>
My aim is to simulate events with some random (predefined) delay. I am simulating events in RxJs as below:
var events = [
{id: 1, qty: 23, delayMs: 0},
{id: 1, qty: 231, delayMs: 3},
{id: 1, qty: 232, delayMs: 1},
{id: 1, qty: 233, delayMs: 2},
{id: 1, qty: 234, delayMs: 100},
{id: 1, qty: 235, delayMs: 50},
{id: 1, qty: 236, delayMs: 50},
{id: 1, qty: 237, delayMs: 50},
{id: 1, qty: 238, delayMs: 50},
{id: 1, qty: 239, delayMs: 50},
{id: 1, qty: 2310, delayMs: 50},
{id: 1, qty: 2311, delayMs: 50},
{id: 1, qty: 2312, delayMs: 100},
{id: 1, qty: 2313, delayMs: 50}
];
var rawEvents$ = O.from(events).map(o => O.return(o).delay(o.delayMs)).concatAll();
With the above code, I get the simulated stream of events as expected. I am trying to implement the same in Java, but looks like Java doesn't have concatAll(). The code that I have written so far:
Observable rawEvents$ = Observable.concat(Observable.from(events).map(o -> Observable.just(o).delay(o.get("delayMs"), TimeUnit.MILLISECONDS)));
But, since I used concat() instead of concatAll(), I was not able to output stream of events with the designated delay. What is the equivalent of concatAll() in java?
Not an expert in RxJAva, but I think it is worth trying with concatMap (should be equivalent to map(...).concatAll). If ordering is not correct, I would try ordering the events array by increasing delay.