You can use the reduce :
data.reduce((a,v) => a = a + v.prix , 0 )
const data = [
{title : "One",prix:100},
{title : "Two",prix:200},
{title : "Three",prix:300}
]
console.log((data.reduce((a,v) => a = a + v.prix , 0 )))
Answer from Vivek Doshi on Stack OverflowYou can use the reduce :
data.reduce((a,v) => a = a + v.prix , 0 )
const data = [
{title : "One",prix:100},
{title : "Two",prix:200},
{title : "Three",prix:300}
]
console.log((data.reduce((a,v) => a = a + v.prix , 0 )))
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in single output value.
arr.reduce(callback, initialValue);
reducer will only return one value and one value only hence the name reduce. Callback is a function to be run for each element in the array.
and Function arguments function(total,currentValue, index,arr):
Argument Description
total Required.The initialValue, or the previously returned value of the function
currentValue Required.The value of the current element
currentIndex Optional.The array index of the current element
arr Optional.The array object the current element belongs to
in this example use this code:
const data = [
{title:"One",prix:100},
{title:"Two",prix:200},
{title:"Three",prix:300}
];
const result = data.reduce((total, currentValue) => total = total + currentValue.prix,0);
console.log(result); // 600
So I have a react app that calculates the sum of inputs. It has an add row button (addRow function) to add Input Component that takes the values to be summed. Each Input component has delete (deleteRow) and disable (disableRow) button as well as select operation (+ or -)
Now the problem is that I lifted up the input values from Input to App via calculate but how can I actually sum up all input values?
App.js
import "./App.css";
import React, { useState } from "react";
import Input from "./components/Input";
function App() {
const [newRow, setNewRow] = useState([]);
const [result, setResult] = useState(0);
const addRow = (event) => {
event.preventDefault();
setNewRow((prev) => [...prev, Math.random()]);
};
const deleteRow = (key) => {
let filteredRows = [...newRow];
filteredRows = filteredRows.filter((input) => input !== key);
setNewRow(filteredRows);
};
const calculate = (result) => {
setResult(result);
}
return (
<div className="App">
<div className="calculator">
<h3>React calculator</h3>
<button onClick={addRow}>Add row</button>
<ul>
{newRow.map((item) => (
<Input
key={item}
myKey={item}
deleteRow={deleteRow}
calculate={calculate} />
))}
</ul>
<div id="sumID" className="sum-styles">{result}</div>
</div>
</div>
);
}
export default App;Input.js
import "./Input.css";
import React, { useState, useRef } from "react";
const Input = (props) => {
const inputRef = useRef();
const selectRef = useRef();
const [numbers, setNumbers] = useState({
operator: "",
number: "",
});
const disableRow = () => { i
nputRef.current.disabled = "true";
};
const inputHandler = (event) => {
event.preventDefault();
selectHandler();
setNumbers((prev) => {
return {
...prev,
number: event.target.value,
};
});
props.calculate(Object.values(numbers));
};
const selectHandler = () => {
const operatorVal = selectRef.current.value;
setNumbers((prev) => {
return {
...prev,
operator: operatorVal,
};
});
};
return (
<li className="item">
<select
className="select__operator"
ref={selectRef}
onChange={selectHandler}>
<option value="+">+</option>
<option value="-">-</option>
</select>
<div>
<span className="num">{Object.values(numbers)}</span>
<input
type="text"
ref={inputRef}
name="number"
placeholder="Enter your number here..."
className="input__number"
onChange={inputHandler}/>
</div>
<button onClick={() => props.deleteRow(props.myKey)}>Delete</button>
<button onClick={disableRow}>Disable</button>
</li>
); };
export default Input;How to display sum of the values entered in input box in react.js?
typescript - ReactJs calculate sum of all values present in Table column - Stack Overflow
Displaying the Sum of values in React JSX
How to calculate the total sum from numbers in textarea?
you can split the value with "," and and find the sum of the array:
export default function App() {
const [first, setfirst] = useState(0)
const addChange=(e)=>{
const sumArr = e.target.value.split(",");
const sum = sumArr.reduce(function(a, b){
return parseInt(a) + parseInt(b);
}, 0);
if(sum) {
setfirst(sum);
}
}
return (
<div className="App">
<>
<label>Sum of inputs:{first} <input type="text" onChange={addChange}></input></label>
</>
</div>
);
}
codesandbox
You have to take the value of your input as a string and do a split (",") to remove each number from the string and parse them to number. After that you have to add each number together to get the sum .
I would get the sum using reduce:
const SumValue = this.state.value && this.state.value.reduce((a, v) => a + v, 0)
1) initial columnNames and array list
state = {
callList: [],
columnModel: [
{ columnName: "date" },
{ columnName: "totalCalls" },
{ columnName: "answeredCalls" },
{ columnName: "abandonedCalls" },
{ columnName: "abandonRate" },
{ columnName: "avgAnswerSpeed" },
]
};
2) Get data from api and prepare array data
try {
const { errors, list, success } = (await apiService.getCalls(request)).data;
if (success) {
// first list is normal numbers count only,
// if you want count avg sum for some columns send second param array list and include column names
// now i want count avg for 'abandonRate', 'avgAnswerSpeed' , others just count sum
this.setState({
callList: list,
callListSum: this.sumCount(
list,
['abandonRate', 'avgAnswerSpeed']
)
})
}
} catch (error) {
console.log(error);
}
sumCount = (list = [], avgColumns = []) => {
const sum = {};
// count numbers
list.map((item) => {
Object.entries(item).map(([key, val]) => {
if (typeof (val) === 'number') {
sum[key] = sum[key] ? (sum[key] + val) : val;
}
})
});
// count avg
avgColumns.map(key => {
if (sum[key]) {
sum[key] = sum[key] / list.length;
}
})
return sum;
}
3) Render data
<table>
<thead>
<tr style={{ backgroundColor: "#F5F7FA" }}>
{
this.state.columnModel.map((item, i) =>
<th key={i}> {item.columnName}</th>
)
}
</tr>
</thead>
<tbody>
{
this.state.callList.map(
(info, index) => (
<tr
key={index}
>
{
this.state.columnModel.map((item, i) =>
(
<td key={i}>
{info[item.columnName]}
</td>
)
)
}
</tr>
)
)}
{/* Render sum area */}
<tr
style={{ backgroundColor: "#F5F7FA" }}
>
{
this.state.columnModel.map((item, i) =>
(
<td style={{ fontWeight: "bold" }} >
{this.state.callListSum[item.columnName]}
</td>
)
)
}
</tr>
</tbody>
</table>
Reduce is an array function, not a meal object function. Try replacing the forEach with the reduce.
meals.reduce((totalCalories, meal) => totalCalories + meal.calorie, 0)
The first reduce assumes calories are numbers, the second is if strings
const meals = [
{ calorie: 10},
{ calorie: 15},
{ calorie: 20}
];
const calorieTotal = meals.reduce((totalCalories, meal) => totalCalories + meal.calorie, 0);
console.log(calorieTotal); // 45 calories
const mealsAsStrings = [
{ calorie: '11'},
{ calorie: '12'},
{ calorie: '13'}
];
const calorieStringTotal = mealsAsStrings.reduce((totalCalories, meal) => totalCalories + parseInt(meal.calorie, 10), 0);
console.log(calorieStringTotal); // 36 calories
You can't use reduce method on array elements as it's an array method. In the example above you are looping into the array and trying to call reduce with each element of array which is not right. You can do as follows -
this.state.meals.reduce((accumulator, currentValue) => accumulator + currentValue)
Hope that helps.
UPDATE - As you are trying to calculate calories from meal object array, we can do it as follows -
this.state.meals.reduce((accumulator, currentValue)=> accumulator + accumulator, currentValue.calorie,0);
Check the link for detail use of reduce method - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
I have a textarea of type text and I want to check if I have numbers and calculate the total value and show it to another input of type number. Here is what I have tried so far:
const [state, setState] = useState({ price: "", items: "" });
const handleInputChange = event => { setState({ ...state, [event.target.name]: event.target.value }); testvalues() };
const calculatValues = () => { let total = 0; const str = state.items const regex = /[+-]?([0-9]*[.,])?[0-9]+/g; const m = regex.exec(str)
while (m !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
m[0] = m[0].replace(',', '.');
total = total + parseFloat(m[0]);
}
setState({ ...state, price: total.toFixed(2) });}
const testvalues = () => { let sum; if (state.items) { sum = state.items.match(/[0-9.]+/g).reduce((acc, curr) => { const number = +acc + Number(curr) return number }, 0) } console.log(sum) }
I think you're mistaking the use of Array.map. Array.map will create a new array and apply what is return from the call back function on each element, you can read more here. With that said, the setState in processData will basically do nothing since your data is not change and you're setting state with what you initialize the state with. To use the new map value, you can assign that to a variable or constant and use that like below:
...
const processData = () => {
var rowWithSum = data.map((item) => {
var currRowValues = Object.entries(item);
var nd = currRowValues.reduce((a, [key, value]) => {
if(key === 'sum'){
return a
}
return a + value;
}, 0);
return {...item, sum: nd};
});
setData(rowWithSum);
};
...
I've also modify so that it create a new key in the object using spread operator, which you can read more on it here, and also to not accidentally add the existing sum to the next sum by check the key using Object.entries.
You're not getting a re-render because React does a referential equality comparison of props/state when making a decision to re-render.
data has the same reference as the original state data array because of which the functional component does not re render on setData
Change setData(data) to setData([...data]) which returns a new copy of the array.
You can have a look on how to update objects and arrays in state - https://beta.reactjs.org/apis/usestate#updating-objects-and-arrays-in-state
const number = movies.map((movie) => movie.price);
const sum = number.reduce(function(a, b) {
return a + b;
}, 0);
I have 2 inputs one for the movie name and other for the price I'm trying to get the total price on the nav... I get the total price but when a add something it doubles the total number
this is the exercise I'm studying from
https://www.youtube.com/watch?v=35lXWvCuM8o
You can use Javascript's reduce function. This is basically the same as @epascarello answer but in ES6 syntax.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
const arr = [{level:2},{level:4},{level:5}];
const total = arr.reduce((prev,next) => prev + next.level,0);
console.log(total);
Either a simple loop
var a = [{level:1},{level:2},{level:3},{level:4}],
total = 0;
for (var i=0; i<a.length; i++) {
total += a[i].level;
}
console.log('total', total)
or reduce
var a = [{level:1},{level:2},{level:3},{level:4}]
console.log(a.reduce( function(cnt,o){ return cnt + o.level; }, 0))