【问题标题】:Create a Dictionary/Object from a JQuery Response从 JQuery 响应创建字典/对象
【发布时间】:2020-12-13 22:53:51
【问题描述】:

这个 JQuery $$('tbody[class="MuiTableBody-root"]')[5].innerText 返回

"Subtotal   $0.00
Total   $0.00
Total Price/Unit    $0.00"

美元金额后有一个换行符,字符串中有额外的空格。

如何插入/或创建字典来存储上述响应,如下所示?

商店 = { “小计”:0.00 美元, “总计”:0.00 美元, “总价格/单位”:0.00 美元 }

DOM:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>

<tbody class="MuiTableBody-root">
  <tr class="MuiTableRow-root">
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">Subtotal</td>
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">$0.00</td>
  </tr>
  <tr class="MuiTableRow-root">
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">Total</td>
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">$0.00</td>
  </tr>
  <tr class="MuiTableRow-root">
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">Total Price/Unit</td>
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">$0.00</td>
  </tr>
</tbody>
</table>

我在响应中尝试了正则表达式。为什么只匹配2?

【问题讨论】:

  • 捕获单个修剪过的单元格文本可能更简单。示例行 html 是什么样的?见minimal reproducible example
  • @charlietfl 我可以使用不同的选择器来获取每一行。你只是在建议吗?

标签: javascript webdriver-io


【解决方案1】:

您可以使用与matchAll() 一起应用的正则表达式来返回匹配的迭代器,您可以使用Array.from() 将其映射到[key, value] 对的数组,然后可以将其传递给Object.fromEntries 以产生最终对象。

const response = `Subtotal   $0.00
Total   $0.00
Total Price/Unit    $0.00`

const regex = /(.*?)(?=\$)(\$\d+.\d+)(?=[\r|\n]|$)/g;

// return iterator from matchAll() 
const matchIterator = response.matchAll(regex);

// pass the iterator to Array.from() and use built in map() 
// to return a [key, value] array with white space removed by trim()
const keyValueArr = Array.from(matchIterator, ([_, key, value]) => ([key.trim(), value.trim()]));

// pass the array to Object.fromEntries()
const finalObject = Object.fromEntries(keyValueArr);

// Or all in one call...
const 
  reg = /(.*?)(?=\$)(\$\d+.\d+)(?=[\r|\n]|$)/g,
  object = Object.fromEntries(
    Array.from(response.matchAll(reg), ([_, key, value]) => ([key.trim(), value.trim()])));

const response = `Subtotal   $0.00
Total   $0.00
Total Price/Unit    $0.00`

const 
  reg = /(.*?)(?=\$)(\$\d+.\d+)(?=[\r|\n]|$)/g,
  object = Object.fromEntries(
    Array.from(response.matchAll(reg), ([_, key, value]) => ([key.trim(), value.trim()])));


console.log(object);

或者使用DOM遍历

const 
  rows = document.querySelectorAll('.MuiTableBody-root tr'),
  object = Object.fromEntries(
      [...rows].map(r => [...r.cells].map(c => c.innerText.trim()))
    );

console.log(object);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>

<tbody class="MuiTableBody-root">
  <tr class="MuiTableRow-root">
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">Subtotal</td>
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">$0.00</td>
  </tr>
  <tr class="MuiTableRow-root">
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">Total</td>
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">$0.00</td>
  </tr>
  <tr class="MuiTableRow-root">
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">Total Price/Unit</td>
    <td class="MuiTableCell-root jss93 MuiTableCell-body MuiTableCell-alignRight">$0.00</td>
  </tr>
</tbody>
</table>

【讨论】:

    【解决方案2】:

    我猜你需要这样的东西

    let res = `Subtotal   $0.00
    Total   $0.00
    Price/Unit    $0.00`;
    
    let parts = res.split('\n').map(item => item.split(' ').filter( i=> i != ""));
    
    let myObj = parts.reduce(function(map, obj) {
        map[obj[0]] = obj[1];
        return map;
    }, {});
    

    【讨论】:

    • 您需要考虑其中可能包含空格的键 - Total Price/Unit 而不是 Price/Unit
    【解决方案3】:

    通过迭代每个行和单元格的单个修剪文本值来将多个 tbody 元素映射到对象数组

    const data = $('tbody.MuiTableBody-root').map((i, tbod) => {
      return [...tbod.rows].reduce((a, row) => {
        const [k, v] = [...row.cells].map(cell => cell.textContent.trim())
        return (a[k] = v, a);   
      }, {})
    }).get();
    
    console.log(data)
    .as-console-wrapper {max-height: 100%!important;top:0}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <table>
      <tbody class="MuiTableBody-root">
        <tr>
          <td>Subtotal</td>
          <td>$0.00</td>
        </tr>
        <tr>
          <td>Total</td>
          <td>$0.00</td>
        </tr>
        <tr>
          <td>Total Price/Unit</td>
          <td>$0.00</td>
        </tr>
      </tbody>
      <tbody class="MuiTableBody-root">
        <tr>
          <td>Subtotal</td>
          <td>$1.00</td>
        </tr>
        <tr>
          <td>Total</td>
          <td>$1.00</td>
        </tr>
        <tr>
          <td>Total Price/Unit</td>
          <td>$1.00</td>
        </tr>
      </tbody>
    </table>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-08
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      • 2020-12-12
      • 2016-01-30
      • 1970-01-01
      相关资源
      最近更新 更多