使用循环构建对象数组,并使用来自相同迭代的计算

时间:2019-09-06 23:13:05

标签: javascript arrays loops object

我正在尝试创建一个对象数组,并使用特定的计算填充它。我目前很困惑,想知道如何使用同一迭代中的数据进行计算。

我很确定前三列按预期工作。但是,最后两列“ TotInterest”和“余额”则不是。


要计算"balance"
我从上一个迭代/期间中提取余额,并添加当前的付款和利息。

要计算"totInterest"
这应该只是当前利息和所有先前利息的总和。


由于第一个期间很特殊,因此我尝试将其添加到循环之前。我认为这引起了某种问题,但我不知道如何解决。

/** UPDATED TABLE OBJECT **/注释了要关注的js代码区域


任何帮助将不胜感激!

编辑:代码中没有错误,但是预期的行为不正确。这是预期/正确结果的图像:https://i.imgur.com/04prTMO.png
余额应将上一次迭代的余额相加,然后加上当前的利息和付款。平衡应该是这样的:
balance: calcTable[i-1].balance + A + calcTable[i].interest
总的兴趣应将当前兴趣与所有之前的迭代相加

//************* CALCULATIONS *************

var Pre = document.getElementById("calc_P").value;
var P = parseFloat(Pre);
var r = document.getElementById("calc_r").value / 100;
var n = 12;
var tre = document.getElementById("calc_t").value;
var t = parseFloat(tre);
var Are = document.getElementById("calc_A").value;
var A = parseFloat(Are);
var p = 12;

var nper = p * t;
var rate = (1 + r / n) ** (n / p) - 1;
var F = P * (1 + rate) ** nper + (A * ((1 + rate) ** nper - 1)) / rate;

//************* DEFAULTS ****************

document.getElementById("finalValue").innerHTML = F;

//************* LINK INPUTS *************

// Select all inputs and add event listener.
var inputsArray = document.querySelectorAll("input");
inputsArray.forEach(el => el.addEventListener("input", linkValue));

// Link the range with number inputs
function linkValue(e) {
  var sibling = e.target.previousElementSibling || e.target.nextElementSibling;
  sibling.value = e.target.value;
}

//************* DEFAULT TABLE OBJECT *************

var tableTotalt = [
  {
    Period: 0,
    Payment: "123",
    PPayment: "154",
    Interest: "143",
    CuInterest: "4423",
    Balance: "123"
  },
  {
    Period: 1,
    Payment: "123",
    PPayment: "154",
    Interest: "143",
    CuInterest: "4423",
    Balance: "123"
  },
  {
    Period: 2,
    Payment: "123",
    PPayment: "154",
    Interest: "143",
    CuInterest: "4423",
    Balance: "123"
  },
  {
    Period: 3,
    Payment: "123",
    PPayment: "154",
    Interest: "143",
    CuInterest: "4423",
    Balance: "123"
  },
  {
    Period: 4,
    Payment: "123",
    PPayment: "154",
    Interest: "143",
    CuInterest: "4423",
    Balance: "123"
  },
  {
    Period: 5,
    Payment: "123",
    PPayment: "154",
    Interest: "143",
    CuInterest: "4423",
    Balance: "123"
  }
];

//************* UPDATED TABLE OBJECT *************

//test-array
var calcTable = new Array(nper);

calcTable.unshift({
  period: 0,
  payment: 0,
  totPayment: 10000,
  interest: 0,
  totInterest: 0,
  balance: 10000
});
console.log(calcTable);
for (let i = 0; i < nper; i += 1) {
  calcTable[i + 1] = {
    period: i + 1,
    payment: A,
    totPayment: (P += A),
    interest: calcTable[i].balance * rate,
    totInterest: calcTable[i].balance * rate + calcTable[i].interest,
    balance: calcTable[i].balance + A + calcTable[i].interest
  };
}

//************* CREATE HTML TABLE *************

var selectorTotalt = "TblCalc";

//call the jsonToTable Function
jsonToTable(calcTable, selectorTotalt);

function addEl(parent, nodeName, className) {
  var element = document.createElement(nodeName);
  if (className) element.className = className;
  if (parent) parent.appendChild(element);
  return element;
}
function addText(parent, text) {
  parent.appendChild(document.createTextNode(text));
}
function jsonToTable(json, selector) {
  var table = addEl(null, "table", "tbl-container");
  var tbody = addEl(table, "tbody");
  var thr = addEl(tbody, "tr", "tbl-headers");

  //loop through the property names of the first object
  for (var propertyName in json[0]) {
    addText(addEl(thr, "th"), propertyName);
  }

  //loop through the array of objects
  for (var ind = 0; ind < json.length; ind++) {
    var item = json[ind];
    var tr = addEl(tbody, "tr", "tbl-rows");
    //loop though each of the objects properties
    var first = ind != json.length - 1; // no first item for last row
    for (var key in item) {
      var el = addEl(tr, "td");
      if (first) {
        // <---- point of interest
        el = addEl(el, "div", "tbl-name-container ");
        el = addEl(el, "div", "tbl-name-text");
        first = false;
      }
      //append the table data containing the objects property value
      addText(el, "" + item[key]);
    }
  }

  var target = document.getElementById(selector);
  target.innerHTML = "";
  target.appendChild(table);
}
<div class="finalValue">Final value: <span id="finalValue">0</span></div>

<!-- INPUTS -->
<div>
  P: <input id="calc_P" type="number" value="10000">
  <input type="range" value="10000"><br>
</div>
<div>
  A: <input id="calc_A" type="number" value="1000">
  <input type="range" value="1000"><br>
</div>
<div>
  t: <input id="calc_t" type="number" value="10">
  <input type="range" value="10"><br>
</div>
<div>
  r: <input id="calc_r" type="number" value="10">
  <input type="range" value="10"><br>
</div>


<!-- TABLE -->
<div id="TblCalc" class="card table-card"></div>


<!-- JS -->
<script type="text/javascript" src="test.js"></script>

2 个答案:

答案 0 :(得分:1)

好的,这是由于您的计算有些偏差,这是正确的代码:

//************* UPDATED TABLE OBJECT *************

//test-array
var calcTable = new Array(nper);

calcTable.unshift({
  period: 0,
  payment: 0,
  totPayment: 10000,
  interest: 0,
  totInterest: 0,
  balance: 10000
});

for (let i = 0; i < nper; i += 1) {
  var interest = calcTable[i].balance * rate;
  calcTable[i + 1] = {
    period: i + 1,
    payment: A,
    totPayment: (P += A),
    interest: interest,
    totInterest: interest + calcTable[i].totInterest,
    balance: calcTable[i].balance + A + interest
  };

}

function setPrecision(table) {
  for (let i = 1; i < table.length; i++) {
    for (let key in table[i]) {
      if (key === 'interest' || key === 'totInterest' || key === 'balance') {
        table[i][key] = table[i][key].toFixed(2);
      }
    }
  }
}

setPrecision(calcTable)

function localeSet(table) {
  for (let i = 1; i < table.length; i++) {
    for (let key in table[i]) {
      if (key === 'interest' || key === 'totInterest' || key === 'balance') {
        table[i][key] = new Intl.NumberFormat('fr', {minimumFractionDigits: 2}).format(table[i][key]);
      } else {
        table[i][key] = new Intl.NumberFormat('fr').format(table[i][key]);
      }
    }
  }
}

localeSet(calcTable);

原始文件中的这一部分导致计算错误:

totInterest: calcTable[i].balance * rate + calcTable[i].interest,
balance: calcTable[i].balance + A + calcTable[i].interest

您想将当前利率添加到余额中,而不是之前计算中的利息。我只是将其存储在变量中并以这种方式传递,因此您不必重新键入计算:

var interest = calcTable[i].balance * rate;

我添加了一些辅助函数setPrecision和localeSet,其格式将类似于您在注释中共享的示例。

这是您想要的:

enter image description here

这是我的版本会得到的:

enter image description here

我还认为您可以进行一些重构,所涉及的部分会更容易理解

//test-array
let calcTable = [];

calcTable.push({
  period: 0,
  payment: 0,
  totPayment: 10000,
  interest: 0,
  totInterest: 0,
  balance: 10000
});

for (let i = 1; i < nper; i++) {
  let previous = i - 1;
  let interest = calcTable[previous].balance * rate;
  calcTable[i] = {
    period: i,
    payment: A,
    totPayment: (P += A),
    interest,
    totInterest: interest + calcTable[previous].totInterest,
    balance: calcTable[previous].balance + A + interest
  };
}

您实际上不需要使用以下命令设置数组的长度:

let calc = new Array(nper);

您可以将calc设为一个空数组:

let calc = [];

然后,无需调用unshift,您只需将第一个计算压入空数组即可。在“ for”循环中,即使您确实不需要索引,也从索引0开始,仅从索引1开始,然后创建一个局部变量“ previous”以读取先前的索引,它将使逻辑看起来像我想不要那么困惑:

for (let i = 1; i < nper; i++) {
  let previous = i - 1;

答案 1 :(得分:1)

没有进行完整的重构(或彻底地梳理了您的代码),但是请尝试一下。我认为大部分问题都在计算循环中,您指的是总利息和利息的先前值,而不是当前值。

此问题已更新,现在循环从第一个索引开始,从而比从前一个索引回溯并通过{{ 1}})。

我在使用Bootstrap时还享有其他一些自由,并根据更改进行了计算。随时更新和修改。

-1
+1