如何在 javascript 映射函数中创建累积变量
How to create an accumulation variable within javascript mapping function
我在 React 中创建了一个 table。我使用 javascript 来映射包含呈现动态 table 所需的所有信息的对象。我的几个列包含数字,我想将这些列相加到附加列中的给定点。下面是我的 table.
的例子
我们的想法是,余额栏将汇总截至该点的整个借方栏。所以第一行的余额单元格应该显示 50(就像它一样)。但是,余额栏中的第二个单元格需要说 100(截至该点的借方栏中所有单元格的总和)。这是我用来映射对象(存储在状态中)以填充 table 的反应代码。请注意,余额列未存储在对象中...我试图以某种方式在映射函数中创建此列值。
<table id="transactionDetailDisplay">
<tr>
<th>#</th>
<th>Account</th>
<th>Description</th>
<th>Debit</th>
<th>Credit</th>
<th>Balance</th>
</tr>
{this.state.transactionObject.map((item =>
<tr>
<td>{}</td>
<td>{item.AccountID}</td>
<td>{item.Description}</td>
<td>{item.Debit}</td>
<td>{item.Credit}</td>
<td>{item.Debit}</td>
</tr>))}
</table>
我想做的是在我的地图函数中添加一个变量作为累加器。例如,我不想将最后一个 table 数据项表示为 item.Debit,而是想将 item.Debit 存储在一个变量中,然后将该变量值放入 table 数据行.在映射函数的每个循环中,我都会将 item.Debit 添加到变量以累积要在 Balance 中显示的正确总和。但是,我无法找出正确的 javascript 来在映射函数和/或 table 标记中创建变量累加器。我认为因为它在 table 标记内,所以我不能像在其他地方那样定义一个变量。有没有办法可以做到这一点,也许用特殊的语法?有谁知道有什么技巧可以帮助我吗?非常感谢任何想法!!
您可以预先创建一个变量,然后添加到地图回调中。
{
(() => {
let debit = 0;
return this.state.transactionObject.map((item) => {
debit += item.Debit;
return (
<tr>
<td>{ }</td>
<td>{item.AccountID}</td>
<td>{item.Description}</td>
<td>{item.Debit}</td>
<td>{item.Credit}</td>
<td>{debit}</td>
</tr>);
})
})()
}
您还可以考虑在渲染之前创建一个借方数组。
let debit = 0;
const debits = this.state.transactionObject.map(item => debit += item.debit);
{
this.state.transactionObject.map((item, i) =>
<tr>
<td>{ }</td>
<td>{item.AccountID}</td>
<td>{item.Description}</td>
<td>{item.Debit}</td>
<td>{item.Credit}</td>
<td>{debits[i]}</td>
</tr>
)
}
您可以通过将数组切片到该点并将其相加来使其发挥作用,但这会增加 O(n ^ 2)
的复杂性。
const debits = this.state.transactionObject.map((_, i, arr) => (
arr.slice(0, i + 1).reduce((a, b) => a + b)
));
Array.prototype.map
函数回调应该是 纯函数 ,即没有像改变余额值这样的副作用。使用 Array.prototype.reduce
将数组缩减为单个值。
const balance = this.state.transactionObject.reduce(
(balance, { Debit }) => balance + Debit,
0,
);
如果您需要计算多个总计,您可以减少到一个具有不同属性的对象来表示您需要的总计,这样您仍然只需迭代数组一次来计算它们。
编辑
我想我最初误解了你的要求,你想显示到当前行为止的累计余额。
首先预先计算每行的余额。
const arr = this.state.transactionObject.map((item, index, arr) => ({
...item,
Balance: arr[index - 1]?.Balance ?? 0) + item.Debit ?? 0
}));
...
{arr.map((item =>
<tr>
<td>{}</td>
<td>{item.AccountID}</td>
<td>{item.Description}</td>
<td>{item.Debit}</td>
<td>{item.Credit}</td>
<td>{item.Balance}</td>
</tr>)
)}
我在 React 中创建了一个 table。我使用 javascript 来映射包含呈现动态 table 所需的所有信息的对象。我的几个列包含数字,我想将这些列相加到附加列中的给定点。下面是我的 table.
的例子我们的想法是,余额栏将汇总截至该点的整个借方栏。所以第一行的余额单元格应该显示 50(就像它一样)。但是,余额栏中的第二个单元格需要说 100(截至该点的借方栏中所有单元格的总和)。这是我用来映射对象(存储在状态中)以填充 table 的反应代码。请注意,余额列未存储在对象中...我试图以某种方式在映射函数中创建此列值。
<table id="transactionDetailDisplay">
<tr>
<th>#</th>
<th>Account</th>
<th>Description</th>
<th>Debit</th>
<th>Credit</th>
<th>Balance</th>
</tr>
{this.state.transactionObject.map((item =>
<tr>
<td>{}</td>
<td>{item.AccountID}</td>
<td>{item.Description}</td>
<td>{item.Debit}</td>
<td>{item.Credit}</td>
<td>{item.Debit}</td>
</tr>))}
</table>
我想做的是在我的地图函数中添加一个变量作为累加器。例如,我不想将最后一个 table 数据项表示为 item.Debit,而是想将 item.Debit 存储在一个变量中,然后将该变量值放入 table 数据行.在映射函数的每个循环中,我都会将 item.Debit 添加到变量以累积要在 Balance 中显示的正确总和。但是,我无法找出正确的 javascript 来在映射函数和/或 table 标记中创建变量累加器。我认为因为它在 table 标记内,所以我不能像在其他地方那样定义一个变量。有没有办法可以做到这一点,也许用特殊的语法?有谁知道有什么技巧可以帮助我吗?非常感谢任何想法!!
您可以预先创建一个变量,然后添加到地图回调中。
{
(() => {
let debit = 0;
return this.state.transactionObject.map((item) => {
debit += item.Debit;
return (
<tr>
<td>{ }</td>
<td>{item.AccountID}</td>
<td>{item.Description}</td>
<td>{item.Debit}</td>
<td>{item.Credit}</td>
<td>{debit}</td>
</tr>);
})
})()
}
您还可以考虑在渲染之前创建一个借方数组。
let debit = 0;
const debits = this.state.transactionObject.map(item => debit += item.debit);
{
this.state.transactionObject.map((item, i) =>
<tr>
<td>{ }</td>
<td>{item.AccountID}</td>
<td>{item.Description}</td>
<td>{item.Debit}</td>
<td>{item.Credit}</td>
<td>{debits[i]}</td>
</tr>
)
}
您可以通过将数组切片到该点并将其相加来使其发挥作用,但这会增加 O(n ^ 2)
的复杂性。
const debits = this.state.transactionObject.map((_, i, arr) => (
arr.slice(0, i + 1).reduce((a, b) => a + b)
));
Array.prototype.map
函数回调应该是 纯函数 ,即没有像改变余额值这样的副作用。使用 Array.prototype.reduce
将数组缩减为单个值。
const balance = this.state.transactionObject.reduce(
(balance, { Debit }) => balance + Debit,
0,
);
如果您需要计算多个总计,您可以减少到一个具有不同属性的对象来表示您需要的总计,这样您仍然只需迭代数组一次来计算它们。
编辑
我想我最初误解了你的要求,你想显示到当前行为止的累计余额。
首先预先计算每行的余额。
const arr = this.state.transactionObject.map((item, index, arr) => ({
...item,
Balance: arr[index - 1]?.Balance ?? 0) + item.Debit ?? 0
}));
...
{arr.map((item =>
<tr>
<td>{}</td>
<td>{item.AccountID}</td>
<td>{item.Description}</td>
<td>{item.Debit}</td>
<td>{item.Credit}</td>
<td>{item.Balance}</td>
</tr>)
)}