简体   繁体   English

如何优化多个 Array.find()

[英]how to optimize multiple Array.find()

I have JSON: (It has way too many rows, but would be too long to paste whole json)我有 JSON:(它的行太多,但是粘贴整个 json 太长了)

"data": {
  "rows": [
      {
          "row_no": "130",
          "sum_begin_period": "3234122.29",
          "sum_end_period": "3099063"
      },
      {
          "row_no": "150",
          "sum_begin_period": "1252394",
          "sum_end_period": "986382"
      },
      {
          "row_no": "160",
          "sum_begin_period": "1321400.28",
          "sum_end_period": "1321400"
      },
      {
          "row_no": "210",
          "sum_begin_period": "3367691.4",
          "sum_end_period": "1282444"
      },
      {
          "row_no": "220",
          "sum_begin_period": "2320199.07",
          "sum_end_period": "265000"
      },
      {
          "row_no": "260",
          "sum_begin_period": "1047492.33",
          "sum_end_period": "1017444"
      },
      {
          "row_no": "610",
          "sum_begin_period": "825495.3",
          "sum_end_period": "960385"
      }
  ]
}

I need to do some math operations for which I need values from multiple rows.我需要做一些数学运算,我需要多行的值。 How can I do that elegantly?我怎样才能优雅地做到这一点?
What I have tried till now:我到目前为止所尝试的:
with Array.find():使用 Array.find():

let ccScore;
  for(const row of finance_report){

    const satr_390_1 = finance_report.find((row) => row.row_no === "390");
    const satr_190_1 = finance_report.find((row) => row.row_no === "190");
    const satr_211_1 = finance_report.find((row) => row.row_no === "211");
    const satr_600_1 = finance_report.find((row) => row.row_no === "600");

    if (satr_600_1== 0) return 1;

    ccScore = (satr_390_1 - satr_190_1- satr_211_1) / satr_600_1;

    if (ccScore < 0.5) return 1;
    else if (ccScore >= 0.5 && ccScore < 2) return 3;
    else if (ccScore >= 2) return 5;
  }

Disadvantage of above is Array.find is being repeated way too many times.上面的缺点是 Array.find 被重复了太多次。
with Array.maps(): (searching with IF statement inside a callback of.map()) with Array.maps(): (在 of.map() 回调中使用 IF 语句搜索)

 let accounting_factor;

  accounting_report.map((row) => {
    let summ = 0;
    if (row.row_no === "480") summ += parseInt(row.sum_end_period);
    if (row.row_no === "490") summ += parseInt(row.sum_end_period);

    if (row.row_no === "130") {
      accounting_factor =
        parseInt(row.sum_end_period) > parseInt(summ) ? false : true;
    }
  });

Disadvantage of above is IF being repeated.上面的缺点是 IF 重复。
Is there a more elegant approach which does not force me to repeat my code and enables me to extract objects(from "rows" array) with certain rows.row_no and then do operation?是否有更优雅的方法不会强迫我重复我的代码并使我能够提取具有某些 rows.row_no 的对象(从“rows”数组)然后进行操作?
PS If Array.reduce() can solve the issue, I would appreciate an example of it PS如果 Array.reduce() 可以解决这个问题,我会很感激它的一个例子

Restructure the data as follows重组数据如下

let rows = {}

original.data.rows.forEach(row => rows[row.row_no] = row)

// USAGE
rows[ROW_NUM].sum_end_period

You can try this out, I believe it'll be faster because a key value tuple is an indexed object and the program won't have to iterate over each element in the array.您可以尝试一下,我相信它会更快,因为键值元组是索引的 object 并且程序不必遍历数组中的每个元素。

Map your data to rows using a reduction function. Map 您的数据使用减少 function 到行。

const mapped = data.rows.reduce((a,v)=>{a[v.row_no]=v;return a},{})

Now your rows are indexed by row_no现在您的行由 row_no 索引

mapped['100']

You can also use destructuring in your reduction.你也可以在你的归约中使用解构。 (thanks jsNOOb) (感谢 jsNOOb)

const mapped = data.rows.reduce((a,v)=>({...a, [v.row_no]: v}),{})

Would Array.filter do the job? Array.filter能胜任吗?

 const rowNrsINeed = [220, 130, 800]; const filtered = retrieveData().data.rows.filter(row => rowNrsINeed.find(no => no === +row.row_no)); filtered.forEach( r => console.log(`row: ${r.row_no}; sum_begin_period: ${r.sum_end_period}`) ) for (let row of filtered) { //... do stuff with each found row } function retrieveData() { return { "data": { "rows": [{ "row_no": "130", "sum_begin_period": "3234122.29", "sum_end_period": "3099063" }, { "row_no": "150", "sum_begin_period": "1252394", "sum_end_period": "986382" }, { "row_no": "160", "sum_begin_period": "1321400.28", "sum_end_period": "1321400" }, { "row_no": "210", "sum_begin_period": "3367691.4", "sum_end_period": "1282444" }, { "row_no": "220", "sum_begin_period": "2320199.07", "sum_end_period": "265000" }, { "row_no": "260", "sum_begin_period": "1047492.33", "sum_end_period": "1017444" }, { "row_no": "610", "sum_begin_period": "825495.3", "sum_end_period": "960385" } ] } }; }

Use filter, includes and reduce使用过滤器、包含和减少

const wantedRowIds = [390,190,211,600];
const wantedRows = finance_report.filter(row => wantedRowIds.includes(+row.row_no));

const rowsById = wantedRows.reduce((acc,row) => ({...acc, [row.row_no]:row}),{});

Then use them like ccScore = rowsById[390] - rowsById[190] - rowsById[211] / rowsById[600];然后像ccScore = rowsById[390] - rowsById[190] - rowsById[211] / rowsById[600];一样使用它们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM