【问题标题】:How to change JSON data Dynamically from with Javascript如何使用 Javascript 动态更改 JSON 数据
【发布时间】:2021-04-28 13:28:44
【问题描述】:

我在生成我想要的 JSON 数据时遇到了算法问题。

我得到了一些 JSON 数据,我需要修改这些数据并使用 JS 在客户端显示

JSON 数据:

[
  {
    "ISTNO": "0000",
    "ATWCAN": "A",
    "COLNAME": "A1"
  },
  {
    "ISTNO": "0000",
    "ATWCAN": "B",
    "COLNAME": "A1"
  },
  {
    "ISTNO": "0000",
    "ATWCAN": "A",
    "COLNAME": "A1"
  },
  {
    "ISTNO": "0001",
    "ATWCAN": "D33D",
    "COLNAME": "B12"
  },
  {
    "ISTNO": "0002",
    "ATWCAN": "GG14",
    "COLNAME": "C1C"
  },
  {
    "ISTNO": "0003",
    "ATWCAN": "FFF-13",
    "COLNAME": "C13"
  },
  {
    "ISTNO": "0004",
    "ATWCAN": "F",
    "COLNAME": "D1"
  },
  {
    "ISTNO": "0004",
    "ATWCAN": "ABB",
    "COLNAME": "D1"
  },
  {
    "ISTNO": "0004",
    "ATWCAN": "AAA",
    "COLNAME": "D1"
  },
  {
    "ISTNO": "0004",
    "ATWCAN": "AABA",
    "COLNAME": "D1"
  },
  {
    "ISTNO": "0005",
    "ATWCAN": "",
    "COLNAME": "E1"
  },
  {
    "ISTNO": "0006",
    "ATWCAN": "AGA",
    "COLNAME": "G1"
  },
  {
    "ISTNO": "0007",
    "ATWCAN": "",
    "COLNAME": "AFA"
  },
  {
    "ISTNO": "0008",
    "ATWCAN": "ABA",
    "COLNAME": "FFFX"
  },
  {
    "ISTNO": "0008",
    "ATWCAN": "ATR",
    "COLNAME": "FFFX"
  },
  {
    "ISTNO": "0009",
    "ATWCAN": "BAB",
    "COLNAME": "BB"
  },
  {
    "ISTNO": "0009",
    "ATWCAN": "ABA",
    "COLNAME": "BB"
  },
  {
    "ISTNO": "0009",
    "ATWCAN": "ABBA",
    "COLNAME": "BB"
  }
]

我想要的结果:

我需要上面这张表,所以我需要用 JS 更改数据

我试过了,但是效果不对。

https://jsfiddle.net/ah04b2f9/6/

    var aElements = [];
  var maxRow = 4;
  for (var i = 0; i < maxRow; i++) {
    var oElement = [];
    for (var t = 0; t < objData.length; t++) {
      if (objData[t + 1] !== undefined) {
        while (objData[t].ISTNO === objData[t + 1].ISTNO) {
          if (objData[t].Flag !== "X") {
            oElement[objData[t].COLNAME] = objData[t].ATWCAN;
          }
          objData[t + 1].Flag = "X";
          objData.splice(t, 1);
          t++;
          if (objData[objData.length - 1] === objData[t]) {
            break;
          }
        }
      } else {
        // oElement[objData[t].COLNAME] = objData[t].ATWCAN;
      }

      if (objData[t].Flag2 !== "X" && objData[t].Flag !== "X") {
        oElement[objData[t].COLNAME] = objData[t].ATWCAN;
        objData[t].Flag2 = "X";
      } else {
        //oElement[objData[t].COLNAME] = objData[t].ATWCAN;
      }

    }

    for (var a1 = 0; a1 < objData.length; a1++) {
      objData[a1].Flag = undefined;
    }

    aElements.push(oElement);
  }
  console.log(aElements);
}

【问题讨论】:

    标签: javascript json algorithm dynamic


    【解决方案1】:

    这是一个简化的方法:

    A.确定 json 数组中每个对象的行索引

    B.形成一个对象数组(每行一个对象),其中包含所需的“列名:值”对。

    将这个数组转换成 HTML 表格应该很简单。

    const jsonData = [
      {
        "ISTNO": "0000",
        "ATWCAN": "A",
        "COLNAME": "A1"
      },
      {
        "ISTNO": "0000",
        "ATWCAN": "B",
        "COLNAME": "A1"
      },
      {
        "ISTNO": "0000",
        "ATWCAN": "A",
        "COLNAME": "A1"
      },
      {
        "ISTNO": "0001",
        "ATWCAN": "D33D",
        "COLNAME": "B12"
      },
      {
        "ISTNO": "0002",
        "ATWCAN": "GG14",
        "COLNAME": "C1C"
      },
      {
        "ISTNO": "0003",
        "ATWCAN": "FFF-13",
        "COLNAME": "C13"
      },
      {
        "ISTNO": "0004",
        "ATWCAN": "F",
        "COLNAME": "D1"
      },
      {
        "ISTNO": "0004",
        "ATWCAN": "ABB",
        "COLNAME": "D1"
      },
      {
        "ISTNO": "0004",
        "ATWCAN": "AAA",
        "COLNAME": "D1"
      },
      {
        "ISTNO": "0004",
        "ATWCAN": "AABA",
        "COLNAME": "D1"
      },
      {
        "ISTNO": "0005",
        "ATWCAN": "",
        "COLNAME": "E1"
      },
      {
        "ISTNO": "0006",
        "ATWCAN": "AGA",
        "COLNAME": "G1"
      },
      {
        "ISTNO": "0007",
        "ATWCAN": "",
        "COLNAME": "AFA"
      },
      {
        "ISTNO": "0008",
        "ATWCAN": "ABA",
        "COLNAME": "FFFX"
      },
      {
        "ISTNO": "0008",
        "ATWCAN": "ATR",
        "COLNAME": "FFFX"
      },
      {
        "ISTNO": "0009",
        "ATWCAN": "BAB",
        "COLNAME": "BB"
      },
      {
        "ISTNO": "0009",
        "ATWCAN": "ABA",
        "COLNAME": "BB"
      },
      {
        "ISTNO": "0009",
        "ATWCAN": "ABBA",
        "COLNAME": "BB"
      }
    ];
    
    // determine row index of each object in jsonData array
    let lastIstno;
    let row = 0;
    const dataWithRows = jsonData.map(el => {
      const istno = el.ISTNO;
      row = (istno !== lastIstno) ? 0 : row + 1;
      lastIstno = istno;
      return { iRow: row, ...el };
    });
    
    
    
    // create array of objects (one object per row)
    // containing `COLNAME : ATWCAN` pairs
    const results = dataWithRows.reduce((acc, item) => {
      if (typeof acc[item.iRow] === 'undefined') {
        acc[item.iRow] = {};
      }
      acc[item.iRow][item.COLNAME] = item.ATWCAN;
      return acc;
    }, []);
    
    const pre = document.querySelector('pre');
    pre.innerText = `dataWithRows: ` +
      JSON.stringify(dataWithRows, null, 2);
    pre.innerText += '\n\nresults: ' + JSON.stringify(results, null, 2);
    &lt;pre&gt;&lt;/pre&gt;

    【讨论】:

      【解决方案2】:

      这是一个基于两个简单辅助函数的版本。 group 接受一个函数并返回一个新函数,该函数接受一个数组并将该数组的元素分组为子数组,该函数产生相同的值。当我们用x =&gt; x .COLNAME调用它时,我们会将原始数据分组到列中。

      transpose 在其主对角线上翻转一个数组,用undefined 填充缺失的条目。这会将我们的列数组转换为行数组。

      我们的主要函数restructure 从数据中获取唯一的标题,然后结合grouptranspose 来创建我们的行列表。它看起来像这样:

      // utility functions
      const group = (fn) => (xs) =>
        Object .values (xs .reduce (
          (a, x) => ((a [fn (x)] = [... (a [fn (x)] || []), x]), a),
          {}
        ))
      
      const transpose = m => 
        m [0] .map ((c, i) => m .map (r => r [i]))
      
      
      // main function
      const restructure = (xs) => ({
        headers: [... new Set (xs .map (x => x.COLNAME))],
        rows: transpose (group (x => x.COLNAME) (xs) .map (x => x .map (y => y .ATWCAN)))
      })
      
      
      // sample data
      const input = [{ISTNO: "0000", ATWCAN: "A", COLNAME: "A1"}, {ISTNO: "0000", ATWCAN: "B", COLNAME: "A1"}, {ISTNO: "0000", ATWCAN: "A", COLNAME: "A1"}, {ISTNO: "0001", ATWCAN: "D33D", COLNAME: "B12"}, {ISTNO: "0002", ATWCAN: "GG14", COLNAME: "C1C"}, {ISTNO: "0003", ATWCAN: "FFF-13", COLNAME: "C13"}, {ISTNO: "0004", ATWCAN: "F", COLNAME: "D1"}, {ISTNO: "0004", ATWCAN: "ABB", COLNAME: "D1"}, {ISTNO: "0004", ATWCAN: "AAA", COLNAME: "D1"}, {ISTNO: "0004", ATWCAN: "AABA", COLNAME: "D1"}, {ISTNO: "0005", ATWCAN: "", COLNAME: "E1"}, {ISTNO: "0006", ATWCAN: "AGA", COLNAME: "G1"}, {ISTNO: "0007", ATWCAN: "", COLNAME: "AFA"}, {ISTNO: "0008", ATWCAN: "ABA", COLNAME: "FFFX"}, {ISTNO: "0008", ATWCAN: "ATR", COLNAME: "FFFX"}, {ISTNO: "0009", ATWCAN: "BAB", COLNAME: "BB"}, {ISTNO: "0009", ATWCAN: "ABA", COLNAME: "BB"}, {ISTNO: "0009", ATWCAN: "ABBA", COLNAME: "BB"}]
      
      
      // demo
      console .log (restructure (input))
      .as-console-wrapper {max-height: 100% !important; top: 0}

      从这个输出中,创建一个表应该很容易。这里我们有一个函数,它使用简单的字符串操作和innerHTML 将结果添加到 DOM。但是你应该能够在你使用的任何前端技术中构建类似的东西。

      const makeTable = (xs, {headers, rows} = restructure(xs)) => 
      `<table>
        <thead>
          <tr>${headers .map (h => `<th>${h}</th>`) .join ('')}</tr>
        </thead>
        <tbody>
          ${rows .map (
            row => `<tr>${row .map (
              cell => `<td>${cell || ''}</td>`
            ) .join ('')}</tr>`
          ) .join ('\n    ')}
        </tbody>
      </table>`
      
      document .getElementById ('result') .innerHTML = makeTable (input)
      table {border-collapse: collapse} td, th {border: 1px solid black; padding: .5em} th {background: #ccc}
      <div id="result"></div>
      <script>const group = (fn) => (xs) => Object .values (xs .reduce ((a, x) => ((a [fn (x)] = [... (a [fn (x)] || []), x]), a), {})); const transpose = m => m [0] .map ((c, i) => m .map (r => r [i])); const restructure = (xs) => ({headers: [... new Set (xs .map (x => x.COLNAME))], rows: transpose (group (x => x.COLNAME) (xs) .map (x => x .map (y => y .ATWCAN)))}); const input = [{ISTNO: "0000", ATWCAN: "A", COLNAME: "A1"}, {ISTNO: "0000", ATWCAN: "B", COLNAME: "A1"}, {ISTNO: "0000", ATWCAN: "A", COLNAME: "A1"}, {ISTNO: "0001", ATWCAN: "D33D", COLNAME: "B12"}, {ISTNO: "0002", ATWCAN: "GG14", COLNAME: "C1C"}, {ISTNO: "0003", ATWCAN: "FFF-13", COLNAME: "C13"}, {ISTNO: "0004", ATWCAN: "F", COLNAME: "D1"}, {ISTNO: "0004", ATWCAN: "ABB", COLNAME: "D1"}, {ISTNO: "0004", ATWCAN: "AAA", COLNAME: "D1"}, {ISTNO: "0004", ATWCAN: "AABA", COLNAME: "D1"}, {ISTNO: "0005", ATWCAN: "", COLNAME: "E1"}, {ISTNO: "0006", ATWCAN: "AGA", COLNAME: "G1"}, {ISTNO: "0007", ATWCAN: "", COLNAME: "AFA"}, {ISTNO: "0008", ATWCAN: "ABA", COLNAME: "FFFX"}, {ISTNO: "0008", ATWCAN: "ATR", COLNAME: "FFFX"}, {ISTNO: "0009", ATWCAN: "BAB", COLNAME: "BB"}, {ISTNO: "0009", ATWCAN: "ABA", COLNAME: "BB"}, {ISTNO: "0009", ATWCAN: "ABBA", COLNAME: "BB"}]</script>

      这个解决方案的重要之处在于它将我们的工作分解为可管理的块。在此过程中,我们创建了两个有用的函数,可以在许多项目中重复使用。

      【讨论】:

        猜你喜欢
        • 2018-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-24
        • 2021-01-18
        • 1970-01-01
        相关资源
        最近更新 更多