find sum of amount for group of list - javascript

I am new to Reactjs.
I have below data
Name Amount
Poorna 11000.00
Kumar 2900.00
Ashok 20000.00
Kumar 3020.00
Poorna 15000.00
Output should display like below
Name Amount
Poorna 26000.00
Kumar 5920.00
Ashok 20000.00
Please help me.

Use Array.reduce()
var sample= [
{ Name: 'Poorna', Amount: 50},
{ Name: 'Kumar', Amount: 50},
{ Name: 'Ashok ', Amount: 75},
{ Name: 'Poorna', Amount: 35},
];
var res = sample.reduce((a, obj)=>{
var existItem = a.find(item => item.Name=== obj.Name);
if(existItem){
existItem.Amount += obj.Amount;
return a;
}
a.push(obj);
return a;
}, []);
console.log(res);

Using reduce()
const array = [
{ id: 1, name: 'Poorna', amount: 11000 },
{ id: 2, name: 'Kumar', amount: 2900},
{ id: 3, name: 'Ashok', amount: 20000},
{ id: 3, name: 'Kumar', amount: 3020},
{ id: 3, name: 'Poorna', amount: 15000}
];
let output = Object.values(array.reduce((acc, curr) => {
if (acc[curr.name]) acc[curr.name].amount += curr.amount;
else acc[curr.name] = { ...curr };
return acc;
}, {}));
console.log(output);

You could do it using a Map:
import React from "react";
export default function App() {
const list = [
{ name: 'Poorna', amount: 11000 },
{ name: 'Kumar', amount: 2900 },
{ name: 'Ashok', amount: 20000 },
{ name: 'Kumar', amount: 3020 },
{ name: 'Poorna', amount: 15000 }
];
const map = new Map();
list.forEach(({ name, amount }) =>
map.set(name, map.has(name) ? map.get(name) + amount : amount));
const listItems = [...map.entries()].map(([name, amount]) => <li>{name}: {amount}</li>);
return <ul>{listItems}</ul>;
}

I think below is the best way.
const data = [
{ Name: 'Poorna', Amount: 11000 },
{ Name: 'Kumar', Amount: 2900 },
{ Name: 'Ashok', Amount: 20000 },
{ Name: 'Kumar', Amount: 3020 },
{ Name: 'Poorna', Amount: 15000 },
];
const result = data.reduce((prev, { Name, Amount }) => {
if (prev[Name]) return {...prev, [Name]: prev[Name] + Amount};
return {...prev, [Name]: Amount};
}, {});

This is how you can group the data according to names:
let data = [
{name: "Poorna", salary:11000.0},
{name: "Kumar",salary: 2900.0},
{name: "Ashok", salary:20000.0},
{name: "Kumar", salary:3020.0},
{name: "Poorna", salary:15000.0},
];
let sol = {};
for (let a of data) {
if (sol[a.name]) {
sol[a.name] += a.salary;
} else {
sol[a.name] = a.salary;
}
}
console.log(sol);
Here is full react app:
import React, { useState, useEffect } from "react";
import "./style.css";
let data = [
{ name: "Poorna", salary: 11000.0 },
{ name: "Kumar", salary: 2900.0 },
{ name: "Ashok", salary: 20000.0 },
{ name: "Kumar", salary: 3020.0 },
{ name: "Poorna", salary: 15000.0 }
];
export default function App() {
const [initialData, setInitialData] = useState(data);
const [group, setGroup] = useState([]);
const groupData = () => {
let sol = {};
for (let a of initialData) {
if (sol[a.name]) {
sol[a.name] += a.salary;
} else {
sol[a.name] = a.salary;
}
}
setGroup(sol);
};
useEffect(() => {
groupData();
}, []);
return (
<div>
<table>
<tr>
{" "}
<th>Name</th>
<th>Amount</th>
</tr>
{initialData.map(d => (
<tr>
{" "}
<td>{d.name}</td>
<td>{d.salary}</td>
</tr>
))}
</table>
<h2>Grouped data</h2>
<table>
<tr>
<th>Name</th>
<th>Amount</th>
</tr>
{group &&
Object.keys(group).map(key => (
<tr>
<td>{key}</td>
<td>{group[key]}</td>
</tr>
))}
</table>
</div>
);
}
You can find the Working app here : Stackblitz Link

Related

getting sum of previous element from list VUEJS

I am trying to get sum of previous element and add this to the existing list.
This is my current list:
ongoing: [
{
id: 'id1',
name: 'clientName',
productionTime: 15,
},
{
id: 'id2',
name: 'client',
productionTime: '15'
}
],
this is the result I want to achieve:
ongoing: [
{
id: 'id1',
name: 'clientName',
productionTime: 15,
sumofprevious: 15
},
{
id: 'id2',
name: 'client',
productionTime: 15,
sumofprevious: 30 (note: this comes from 15 + 15)
}
],
I use vuejs 3 with Pinia.
I tried many codes/examples but this is the closest one but it doesn't work as I want it. It doesn't read productionTime from ongoing
const thisList = computed(() => {
let array = storeOrders.ongoing.productionTime,
sum = 0,
newarray = array.map(value => sum += value)
return console.log(newarray)
})
You can use computed property:
const { computed, reactive } = Vue
const app = Vue.createApp({
setup() {
let ongoing = reactive([{id: 'id1', name: 'clientName', productionTime: 15,}, {id: 'id2', name: 'client', productionTime: '15'}])
const res = computed(() => {
let sum = 0
return ongoing.map(o => {
sum += +o.productionTime
return {...o, sumofprevious: sum}
})
})
const add = () => {
ongoing.push({id: Math.floor(Date.now() / 1000), name: 'name', productionTime: Math.ceil(Math.random() * 20),})
}
return { ongoing, res, add };
},
})
app.mount('#demo')
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
<div id="demo">
<button #click="add">add</button>
<br />
ongoing: {{ ongoing }}
<br /><br />
result: {{ res }}
</div>
I would try to compute this:
const ongoing = [
{
id: 'id1',
name: 'clientName',
productionTime: 15,
sumOfPrevious: 0,
},
{
id: 'id2',
name: 'client',
productionTime: 15,
}
];
const sumOfPrev = () => {
return ongoing.map((el, i) => {
if (i !== 0) {
el.sumOfPrevious = ongoing[i-1].productionTime + el.productionTime;
}
return el;
})
}
console.log(sumOfPrev());

How to loop through two arrays of objects and get a new array with some data modified?

How to loop through two arrays of objects and get a new array with some data modified?
Arrays:
const products = [
{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Tees',
},
];
const categories = [
{
name: 'Jeans',
},
{
name: 'Tees',
},
];
Need new categories array like this with new prop productCount:
const newCategories = [
{
name: 'Jeans',
productCount: 2,
},
{
name: 'Tees',
productCount: 0,
},
];
I tried this way but it doesn't work:
const newArr = categories.map((category) => {
let count = 0;
const index = products.findIndex((product) => category.name === product.category);
if (index > -1) {
return {
...category,
productCount: count++,
};
}
return {
...category,
productCount: 0,
};
});
Increasing the count number will not in that case because it will always start with zero. Instead, you can use the filter() method to find the number of products with a specific category and assign this number to productCount attribute.
const products = [{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Tees',
},
];
const categories = [{
name: 'Jeans',
},
{
name: 'Tees',
},
];
const newArr = categories.map((category) => {
const numberOfItems = products.filter((product) => category.name === product.category);
return {
...category,
productCount: numberOfItems.length,
};
});
console.log(newArr)
You can create an object and the transform it to array, something like this:
const products = [
{
brand: "Levis",
category: "Jeans"
},
{
brand: "Levis",
category: "Jeans"
},
{
brand: "Levis",
category: "Tees"
}
];
const categoriesObj = {};
products.forEach(({ brand, category }) => {
categoriesObj[category] ??= {
name: category,
productCount: 0
};
++categoriesObj[category].productCount;
});
const newCategories = Object.values(categoriesObj);
console.log(newCategories);
You can use the Array#Map method and add a productCount property using the Array#filter method
const products = [{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Jeans',
},
{
brand: 'Levis',
category: 'Tees',
},
];
const categories = [{
name: 'Jeans',
},
{
name: 'Tees',
},
];
const newCategories = [...categories].map(category => ({
...category,
productCount: products.filter(product => product.category === category.name).length
}))
console.log(newCategories)
You could do this with Array.reduce(), incrementing the productCount for each item. This should also be efficient, requiring only one iteration of the products array.
We'd run the reduce over both arrays, ensuring that we'll end up with a productCount of zero where no products for that category exist.
const products = [ { brand: 'Levis', category: 'Jeans', }, { brand: 'Levis', category: 'Jeans', }, { brand: 'Levis', category: 'Tees', }, ];
const categories = [ { name: 'Jeans', }, { name: 'Tees', }, { name: 'Foo', } ];
const result = Object.values([...categories, ...products].reduce((acc, { brand, category, name }) => {
const key = name || category;
acc[key] = acc[key] || { name: key, productCount: 0 };
if (category) acc[key].productCount++;
return acc;
}, {}));
console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; }

How to sum each value inside array of object to new variable

I have a data like this :
const fund =
[
{
id: 1234,
totalAmount: 0,
data:
[
{
id: 1234,
amount: '4.000'
},
{
id: 1234,
amount: '3.000'
}
]
},
{
id: 12345,
totalAmount: 0
},
{
id: 123456,
totalAmount: 0
data:
[
{
id: 123456,
amount: '3.000'
},
{
id: 123456,
amount: '5.000'
}
]
}
]
I want to sum the amount inside of data each id to a key called totalAmount. But not all the parent id have data key.
here's my desired output :
const fund =
[
{
id: 1234
data:
[
{
id: 1234,
amount: '4.000'
},
{
id: 1234,
amount: '3.000'
}
],
totalAmount: 7000
},
{
id: 12345,
totalAmount: 0
},
{
id: 123456,
data:
[
{
id: 123456,
amount: '3.000'
},
{
id: 123456,
amount: '5.000'
}
],
totalAmount: 8000
}
]
I was trying with this code :
fund.forEach((elA, i) => {
if (elA.data) {
const total = funders[i].data.reduce((acc, curr) => {
acc += parseInt(curr.amount.replace(/\./g, ''))
return acc
})
fund[i] = total ? {...elA, totalAmount: total} : elA;
}
})
But it's not summing like i want.
Where's my mistake ?
Please ask me if you need more information if it's still not enough to solve that case.
You need to define the initial value for the reduce iterator.
fund.forEach((elA, i) => {
if (elA.data) {
const total = funders[i].data.reduce((acc, curr) => {
acc += parseInt(curr.amount.replace(/\./g, ''))
return acc
}, 0)
fund[i] = total ? {...elA, totalAmount: total} : elA;
}
});
Another alternative for the same code:
fund.forEach(elA => {
if (elA.data) {
const total = elA.data.reduce((acc, curr) => {
return acc + parseInt(curr.amount.replace(/\./g, ''))
}, 0)
elA.totalAmount = total;
}
});

How can I can delete item inside array in object of array? javascript

I want to add a field inside each presentsData object called sumP and fill it with the presents item sum.
Second goal, if sumP > money I would like to delete the most expensive item inside
It's not working
const presentsData= [
{
name: "Peter",
presents: ["coffee","holidays"],
money: 7000
},
{
name: "Mario",
presents: ["car","coal"],
money: 300
},
{
name: "Amanda",
presents: ["computer","coal"],
money: 300
},
{
name: "David",
presents: ["clothes", "car"],
money: 2000
}
]
const prices= [
{
present: "coffee",
price: 1
},
{
present: "holidays",
price: 1000
},
{
present: "videogames",
price: 40
},
{
present: "computer",
price: 600
},
{
present: "tattoo",
price: 30
},
{
present: "clothes",
price: 80
},
{
present: "car",
price: 6000
},
{
present: "phone",
price: 800
},
{
present: "motorbike",
price: 3500
},
{
present: "coal",
price: 0
}
]
const pricesMap = new Map(prices.map(({ present, price }) => [present, price]))
const res1 = presentsData.map(s=>{
return {...s,
sumP: s.presents.reduce((acc, p) => acc + pricesMap.get(p),0)
}
})
console.log("this is res1=>",res1) //this is presentsData result after adding the field sumP
console.log(pricesMap)
const res2 = res1.map((r)=>{
if(r.sumP > r.money){
( /* would like to delete the item inside "presents" with the bigger price using pricesMap */)
}
})
console.log(res2)
pd: what I find hard is to find out how to iterate in presents , array inside object inside array.
You can filter the presents and keep removing the most expensive presents until there's money to buy them:
const presentsData = [{
name: "Peter",
presents: ["coffee", "holidays"],
money: 7000
},
{
name: "Mario",
presents: ["car", "coal"],
money: 300
},
{
name: "Amanda",
presents: ["computer", "coal"],
money: 300
},
{
name: "David",
presents: ["clothes", "car"],
money: 2000
}
]
const prices = [{
present: "coffee",
price: 1
},
{
present: "holidays",
price: 1000
},
{
present: "videogames",
price: 40
},
{
present: "computer",
price: 600
},
{
present: "tattoo",
price: 30
},
{
present: "clothes",
price: 80
},
{
present: "car",
price: 6000
},
{
present: "phone",
price: 800
},
{
present: "motorbike",
price: 3500
},
{
present: "coal",
price: 0
}
]
const pricesMap = new Map(prices.map(({
present,
price
}) => [present, price]))
const withSumP = presentsData.map(s => {
return { ...s,
sumP: s.presents.reduce((acc, p) => acc + pricesMap.get(p), 0)
}
})
console.log(withSumP) //this is presentsData result after adding the field sumP
const mostExpensive = (arr) => {
return arr.reduce((acc, el) => {
if (pricesMap.get(el) > pricesMap.get(acc)) {
return el
}
return acc;
})
}
// If you want to remove the most expensive present once for each element
const result = withSumP.map((el) => {
if (el.sumP > el.money) {
const presentToDelete = mostExpensive(el.presents);
return { ...el,
presents: el.presents.filter(p => p !== presentToDelete)
}
}
return el;
})
console.log(result);
// If you want to delete presents until you can buy them and also update sumP to be in sync with the presents:
const resultAlt = withSumP.map((el) => {
let updatedPresents = [...el.presents];
let updatedSumP = el.sumP;
while ((updatedSumP > el.money) && (updatedPresents.length > 0)) {
const presentToDelete = mostExpensive(updatedPresents);
updatedPresents = updatedPresents.filter(p => p !== presentToDelete);
updatedSumP -= pricesMap.get(presentToDelete);
}
return { ...el,
presents: updatedPresents,
sumP: updatedSumP
};
})
console.log(resultAlt)
const deleteMostExpensive = (array, prices) => {
let res = [];
let mostEspensive = array[0];
array.forEach(product => {
let cur = prices.find(p => p.present == product)
if (cur.price > mostEspensive.price)
mostEspensive = cur;
})
array.forEach(e => {
if (e != mostEspensive.present)
res.push(e);
})
return res;
}
const calculSumP = (elt, prices) => {
r = 0;
elt.presents.forEach(e => {
r += prices.find(c => c.present == e).price;
})
return r;
}
presentsData.forEach(elt => {
elt.sumP = calculSumP(elt, prices);
while (elt.sumP > elt.money) {
let newPresents = deleteMostExpensive(elt.presents, prices);
elt.presents = newPresents;
elt.sumP = calculSumP(elt, prices)
}
})
This would be all that's required:
const items = (prices) => {
let obj = {};
for (p of prices) {
obj[p.present] = p.price;
}
return obj;
}
var priceList = items(prices);
presentsData.forEach( (person) => {
let presents = person.presents;
person.sumP = presents.reduce( (acc, current) => {
return acc + priceList[current];
}, 0);
if (person.sumP > person.money) {
presents.sort( (a,b) => priceList[a] - priceList[b]);
presents.pop();
}
});

How to add data from array of object with array inside to another array of object? javascript

This is my code, I want to create another filtered array like the example below, I have 2 arrays and want to add score information to it, I know it's simple but can't find the solution
const wishesData = [
{
name: "Peter",
presents: ["coffee", "holidays"]
},
{
name: "Mario",
presents: ["coffee", "videogames"]
},
{
name: "Amanda",
presents: ["computer", "tattoo"]
}
]
const scoresData= [
{
name: "Peter",
score: 10
},
{
name: "Mario",
score: 2.3
},
{
name: "Amanda",
score: 1.1
}
]
const result = wishesData.map((ele) => {
return {
...ele,
score: scoresData.find(s=> s.name === ele.name? s.score: 0)
}
})
console.log("este es el resultado=>",result)
I want to modify the array wishesData adding "score" to all objects inside and get to look like this example:
{
name: "Mario",
presents: ["coffee", "videogames"],
score: 2.3
}
Please check the example and correction and suggestions.
Correction: scoresData.find(s=> s.name === ele.name? s.score: 0) - here you do not close bracket for Array.find and try to access it's property within find. In your code, you will get scoreData object instead of score.
const match = scoresData.find(s=> s.name === ele.name); // -> ? s.score: 0)
return match ? match.score : 0;
// or simply
const score = scoresData.find(s=> s.name === ele.name)?.score || 0;
Suggestion: it will take O(N^2) time. All iteration for wishesData need another iteration scoresData for each. Why don't you use reduce provided in example?
const scoreMap = scoresData.reduce((a, c) => ({
...a,
[c.name]: c.score
}), {})
// you can easy to find score by
const result = wishesData.map((ele) => {
return {
...ele,
score: scoreMap[ele.name] || 0,
}
})
Thanks
const wishesData = [{
name: "Peter",
presents: ["coffee", "holidays"]
},
{
name: "Mario",
presents: ["coffee", "videogames"]
},
{
name: "Amanda",
presents: ["computer", "tattoo"]
}
]
const scoresData = [{
name: "Peter",
score: 10
},
{
name: "Mario",
score: 2.3
},
{
name: "Amanda",
score: 1.1
}
]
const scoreMap = scoresData.reduce((a, c) => ({
...a,
[c.name]: c.score
}), {})
const result = wishesData.map((ele) => {
return {
...ele,
score: scoreMap[ele.name] || 0,
}
})
console.log("este es el resultado=>", result)
And this is just editing of your origin code
const wishesData = [{
name: "Peter",
presents: ["coffee", "holidays"]
},
{
name: "Mario",
presents: ["coffee", "videogames"]
},
{
name: "Amanda",
presents: ["computer", "tattoo"]
}
]
const scoresData = [{
name: "Peter",
score: 10
},
{
name: "Mario",
score: 2.3
},
{
name: "Amanda",
score: 1.1
}
]
const result = wishesData.map((ele) => {
return {
...ele,
score: scoresData.find(s => s.name === ele.name)?.score || 0
}
})
console.log("este es el resultado=>", result)
You return the whole object, just return the score:
const wishesData = [{
name: "Peter",
presents: ["coffee", "holidays"]
},
{
name: "Mario",
presents: ["coffee", "videogames"]
},
{
name: "Amanda",
presents: ["computer", "tattoo"]
},
{
name: "Another",
presents: ["computer", "tattoo"]
}
]
const scoresData = [{
name: "Peter",
score: 10
},
{
name: "Mario",
score: 2.3
},
{
name: "Amanda",
score: 1.1
}
]
const result = wishesData.map(ele => {
const match = scoresData.find(s => s.name === ele.name)
return { ...ele, score: match ? match.score : 0 }
})
console.log("este es el resultado=>", result)
const wishesWithScores = wishesData.map(wishObject => {
const descriptor = wishObject.name;
const { score } = scoresData.find(({ name }) => name === descriptor);
return {
...wishObject,
score
}
});

Categories

Resources