【问题标题】:Is there an easier/more efficient way to update values in this json file?是否有更简单/更有效的方法来更新此 json 文件中的值?
【发布时间】:2021-04-05 08:09:39
【问题描述】:

所以我有一个 Tampermonkey 脚本正在运行。该脚本使用存储特定过滤器的 json 文件。我必须每天大约三次手动更新这些过滤器的一些值。现在我留下了这个 json 文件,它看起来有点糟糕,编辑起来很痛苦,我将在下面展示它的一部分。

{
"data": {
    "DAVID SILVA RB HUNT": "s{\"searchCriteria\":{\"criteria\":{\"_acquiredDate\":\"\",\"_category\":\"any\",\"_position\":\"any\",\"_sort\":\"desc\",\"_type\":\"player\",\"_untradeables\":\"\",\"_zone\":-1,\"club\":-1,\"count\":21,\"defId\":[],\"excludeDefIds\":[],\"isExactSearch\":false,\"league\":-1,\"level\":\"any\",\"maskedDefId\":168542,\"maxBid\":0,\"maxBuy\":120000,\"minBid\":700,\"minBuy\":0,\"nation\":-1,\"offset\":0,\"playStyle\":266,\"rarities\":[6],\"sortBy\":\"value\",\"subtypes\":[]},\"playerData\":{\"id\":168542,\"firstName\":\"David Josué\",\"lastName\":\"Jiménez Silva\",\"commonName\":\"David Silva\",\"rating\":86}},\"abSettings\":{\"buyPrice\":\"119000\",\"sellPrice\":\"131000\",\"minDeleteCount\":\"50\",\"waitTime\":\"7-15\",\"maxPurchases\":\"1\",\"randMinBid\":\"2000\",\"useRandMinBid\":true,\"telegramBotToken\":\"1499673950:AAFI3vtBhZ72BlMlCbF5qdIp8cptoR_TeyI\",\"telegramChatID\":\"1253533225\",\"telegramBuy\":\"A\",\"notificationEnabled\":true,\"soundEnabled\":true}}",
    "DAVID SILVA RB SHADOW": "s{\"searchCriteria\":{\"criteria\":{\"_acquiredDate\":\"\",\"_category\":\"any\",\"_position\":\"any\",\"_sort\":\"desc\",\"_type\":\"player\",\"_untradeables\":\"\",\"_zone\":-1,\"club\":-1,\"count\":21,\"defId\":[],\"excludeDefIds\":[],\"isExactSearch\":false,\"league\":-1,\"level\":\"any\",\"maskedDefId\":168542,\"maxBid\":0,\"maxBuy\":120000,\"minBid\":650,\"minBuy\":0,\"nation\":-1,\"offset\":0,\"playStyle\":268,\"rarities\":[6],\"sortBy\":\"value\",\"subtypes\":[]},\"playerData\":{\"id\":168542,\"firstName\":\"David Josué\",\"lastName\":\"Jiménez Silva\",\"commonName\":\"David Silva\",\"rating\":86}},\"abSettings\":{\"buyPrice\":\"119000\",\"sellPrice\":\"131000\",\"minDeleteCount\":\"50\",\"waitTime\":\"7-15\",\"maxPurchases\":\"1\",\"randMinBid\":\"2000\",\"useRandMinBid\":true,\"telegramBotToken\":\"1499673950:AAFI3vtBhZ72BlMlCbF5qdIp8cptoR_TeyI\",\"telegramChatID\":\"1253533225\",\"telegramBuy\":\"A\",\"notificationEnabled\":true,\"soundEnabled\":true}}",
    "MAHREZ IF HUNT": "s{\"searchCriteria\":{\"criteria\":{\"_acquiredDate\":\"\",\"_category\":\"any\",\"_position\":\"any\",\"_sort\":\"desc\",\"_type\":\"player\",\"_untradeables\":\"\",\"_zone\":-1,\"club\":-1,\"count\":20,\"defId\":[],\"excludeDefIds\":[],\"isExactSearch\":false,\"league\":-1,\"level\":\"any\",\"maskedDefId\":204485,\"maxBid\":0,\"maxBuy\":117000,\"minBid\":0,\"minBuy\":0,\"nation\":-1,\"offset\":0,\"playStyle\":266,\"rarities\":[3],\"sortBy\":\"value\",\"subtypes\":[]},\"playerData\":{\"id\":204485,\"firstName\":\"Riyad\",\"lastName\":\"Mahrez\",\"commonName\":null,\"rating\":85}},\"abSettings\":{\"buyPrice\":\"113000\",\"sellPrice\":\"125000\",\"minDeleteCount\":\"50\",\"waitTime\":\"7-15\",\"maxPurchases\":\"1\",\"minRate\":\"86\",\"randMinBid\":\"2000\",\"useRandMinBid\":true,\"telegramBotToken\":\"1499673950:AAFI3vtBhZ72BlMlCbF5qdIp8cptoR_TeyI\",\"telegramChatID\":\"1253533225\",\"telegramBuy\":\"A\",\"notificationEnabled\":true,\"soundEnabled\":true}}",
    "MAHREZ IF SHADOW": "s{\"searchCriteria\":{\"criteria\":{\"_acquiredDate\":\"\",\"_category\":\"any\",\"_position\":\"any\",\"_sort\":\"desc\",\"_type\":\"player\",\"_untradeables\":\"\",\"_zone\":-1,\"club\":-1,\"count\":21,\"defId\":[],\"excludeDefIds\":[],\"isExactSearch\":false,\"league\":-1,\"level\":\"any\",\"maskedDefId\":204485,\"maxBid\":0,\"maxBuy\":117000,\"minBid\":1700,\"minBuy\":0,\"nation\":-1,\"offset\":0,\"playStyle\":268,\"rarities\":[3],\"sortBy\":\"value\",\"subtypes\":[]},\"playerData\":{\"id\":204485,\"firstName\":\"Riyad\",\"lastName\":\"Mahrez\",\"commonName\":null,\"rating\":85}},\"abSettings\":{\"buyPrice\":\"113000\",\"sellPrice\":\"125000\",\"minDeleteCount\":\"50\",\"waitTime\":\"7-15\",\"maxPurchases\":\"1\",\"minRate\":\"86\",\"randMinBid\":\"2000\",\"useRandMinBid\":true,\"telegramBotToken\":\"1499673950:AAFI3vtBhZ72BlMlCbF5qdIp8cptoR_TeyI\",\"telegramChatID\":\"1253533225\",\"telegramBuy\":\"A\",\"notificationEnabled\":true,\"soundEnabled\":true}}",

正如我所说,这只是其中的一部分。它像这样延伸了大约 200 行。每行我必须编辑 3 个值; “maxBuy”、“buyPrice”和“sellPrice”。因为文件是这样格式化的,所以需要很长时间。我尝试将其转换为 csv 进行编辑,然后再转换回 json,但这并没有真正起作用,因为我认为的格式。

非常感谢任何有关如何更轻松地编辑这些值的提示!

编辑:我还尝试以某种方式将 json 文件绑定到数据库以便于编辑,但还是没有运气。然后我尝试使用 python 对其进行编辑,但似乎没有比仅仅浏览/滚动每一行更有效。

【问题讨论】:

  • 您的意思是使用文本编辑器手动编辑文件,而不是使用一段 JavaScript 代码以编程方式编辑它吗?我想说这里的问题不是 JSON,而是自定义(?)内部格式。如果您已经在使用 JSON,为什么不一直使用它呢?
  • 如果数据是通过脚本生成的,那么更新它的责任也应该属于脚本。手动赶不上,既费时又容易出错。
  • 我可以手动执行,但由于它不是我的脚本,我无法控制格式的外观。它只是输出这个文件。如果有一种使用 JS 进行编辑的方法,我完全愿意接受。我想到的是一些简单的事情,比如在 excel 中打开它然后编辑特定值并保存并转换回 json,因为脚本使用该格式的 json 文件,如果这有意义的话?

标签: javascript json database data-entry


【解决方案1】:

您提供的数据不是有效的 JSON。当您想以编程方式处理它时,这一点很重要。

下面的sn-p

  • 将数据转换为 JSON
  • 显示更新数据的表格
  • 单击按钮会在文本区域中创建具有更新值的原始格式

您可以从文本区域复制修改后的结果。我觉得这比文本修改更方便。

const d = {
  "data": {
    "DAVID SILVA RB HUNT": "s{\"searchCriteria\":{\"criteria\":{\"_acquiredDate\":\"\",\"_category\":\"any\",\"_position\":\"any\",\"_sort\":\"desc\",\"_type\":\"player\",\"_untradeables\":\"\",\"_zone\":-1,\"club\":-1,\"count\":21,\"defId\":[],\"excludeDefIds\":[],\"isExactSearch\":false,\"league\":-1,\"level\":\"any\",\"maskedDefId\":168542,\"maxBid\":0,\"maxBuy\":120000,\"minBid\":700,\"minBuy\":0,\"nation\":-1,\"offset\":0,\"playStyle\":266,\"rarities\":[6],\"sortBy\":\"value\",\"subtypes\":[]},\"playerData\":{\"id\":168542,\"firstName\":\"David Josué\",\"lastName\":\"Jiménez Silva\",\"commonName\":\"David Silva\",\"rating\":86}},\"abSettings\":{\"buyPrice\":\"119000\",\"sellPrice\":\"131000\",\"minDeleteCount\":\"50\",\"waitTime\":\"7-15\",\"maxPurchases\":\"1\",\"randMinBid\":\"2000\",\"useRandMinBid\":true,\"telegramBotToken\":\"1499673950:AAFI3vtBhZ72BlMlCbF5qdIp8cptoR_TeyI\",\"telegramChatID\":\"1253533225\",\"telegramBuy\":\"A\",\"notificationEnabled\":true,\"soundEnabled\":true}}",
    "DAVID SILVA RB SHADOW": "s{\"searchCriteria\":{\"criteria\":{\"_acquiredDate\":\"\",\"_category\":\"any\",\"_position\":\"any\",\"_sort\":\"desc\",\"_type\":\"player\",\"_untradeables\":\"\",\"_zone\":-1,\"club\":-1,\"count\":21,\"defId\":[],\"excludeDefIds\":[],\"isExactSearch\":false,\"league\":-1,\"level\":\"any\",\"maskedDefId\":168542,\"maxBid\":0,\"maxBuy\":120000,\"minBid\":650,\"minBuy\":0,\"nation\":-1,\"offset\":0,\"playStyle\":268,\"rarities\":[6],\"sortBy\":\"value\",\"subtypes\":[]},\"playerData\":{\"id\":168542,\"firstName\":\"David Josué\",\"lastName\":\"Jiménez Silva\",\"commonName\":\"David Silva\",\"rating\":86}},\"abSettings\":{\"buyPrice\":\"119000\",\"sellPrice\":\"131000\",\"minDeleteCount\":\"50\",\"waitTime\":\"7-15\",\"maxPurchases\":\"1\",\"randMinBid\":\"2000\",\"useRandMinBid\":true,\"telegramBotToken\":\"1499673950:AAFI3vtBhZ72BlMlCbF5qdIp8cptoR_TeyI\",\"telegramChatID\":\"1253533225\",\"telegramBuy\":\"A\",\"notificationEnabled\":true,\"soundEnabled\":true}}",
    "MAHREZ IF HUNT": "s{\"searchCriteria\":{\"criteria\":{\"_acquiredDate\":\"\",\"_category\":\"any\",\"_position\":\"any\",\"_sort\":\"desc\",\"_type\":\"player\",\"_untradeables\":\"\",\"_zone\":-1,\"club\":-1,\"count\":20,\"defId\":[],\"excludeDefIds\":[],\"isExactSearch\":false,\"league\":-1,\"level\":\"any\",\"maskedDefId\":204485,\"maxBid\":0,\"maxBuy\":117000,\"minBid\":0,\"minBuy\":0,\"nation\":-1,\"offset\":0,\"playStyle\":266,\"rarities\":[3],\"sortBy\":\"value\",\"subtypes\":[]},\"playerData\":{\"id\":204485,\"firstName\":\"Riyad\",\"lastName\":\"Mahrez\",\"commonName\":null,\"rating\":85}},\"abSettings\":{\"buyPrice\":\"113000\",\"sellPrice\":\"125000\",\"minDeleteCount\":\"50\",\"waitTime\":\"7-15\",\"maxPurchases\":\"1\",\"minRate\":\"86\",\"randMinBid\":\"2000\",\"useRandMinBid\":true,\"telegramBotToken\":\"1499673950:AAFI3vtBhZ72BlMlCbF5qdIp8cptoR_TeyI\",\"telegramChatID\":\"1253533225\",\"telegramBuy\":\"A\",\"notificationEnabled\":true,\"soundEnabled\":true}}",
    "MAHREZ IF SHADOW": "s{\"searchCriteria\":{\"criteria\":{\"_acquiredDate\":\"\",\"_category\":\"any\",\"_position\":\"any\",\"_sort\":\"desc\",\"_type\":\"player\",\"_untradeables\":\"\",\"_zone\":-1,\"club\":-1,\"count\":21,\"defId\":[],\"excludeDefIds\":[],\"isExactSearch\":false,\"league\":-1,\"level\":\"any\",\"maskedDefId\":204485,\"maxBid\":0,\"maxBuy\":117000,\"minBid\":1700,\"minBuy\":0,\"nation\":-1,\"offset\":0,\"playStyle\":268,\"rarities\":[3],\"sortBy\":\"value\",\"subtypes\":[]},\"playerData\":{\"id\":204485,\"firstName\":\"Riyad\",\"lastName\":\"Mahrez\",\"commonName\":null,\"rating\":85}},\"abSettings\":{\"buyPrice\":\"113000\",\"sellPrice\":\"125000\",\"minDeleteCount\":\"50\",\"waitTime\":\"7-15\",\"maxPurchases\":\"1\",\"minRate\":\"86\",\"randMinBid\":\"2000\",\"useRandMinBid\":true,\"telegramBotToken\":\"1499673950:AAFI3vtBhZ72BlMlCbF5qdIp8cptoR_TeyI\",\"telegramChatID\":\"1253533225\",\"telegramBuy\":\"A\",\"notificationEnabled\":true,\"soundEnabled\":true}}",
  }
}

// transforming source data format to JSON
const getJSON = (source) => {
  return Object.fromEntries(Object.entries(d.data).map(([key, val]) => {
    return [key, JSON.parse(val.replace(/^s/, ''))]
  }))
}

// writing source data format
const writeObject = (json) => {
  const data = {}
  for (let key in json) {
    data[key] = 's' + JSON.stringify(json[key])
  }
  return {
    data
  }
}

// table row template
const tableRow = ({
  key,
  maxBuy,
  buyPrice,
  sellPrice
}) => {
  html = ''
  html += `
    <tr>
      <td rowspan="3">
        ${ key }
      </td>
      <td>maxBuy</td>
      <td>${ maxBuy }</td>
      <td>
        <input
          data-updateid="${ key },maxBuy"
          type="number"
          value="${ maxBuy }"
        />
      </td>
    </tr>
    <tr>
      <td>buyPrice</td>
      <td>${ buyPrice }</td>
      <td>
        <input
          data-updateid="${ key },buyPrice"
          type="number"
          value="${ buyPrice }"
        />
      </td>
    </tr>
    <tr>
      <td>sellPrice</td>
      <td>${ sellPrice }</td>
      <td>
        <input
          data-updateid="${ key },sellPrice"
          type="number"
          value="${ sellPrice }"
        />
      </td>
    </tr>
  `
  return html
};

(function(json) {
  // deep copying the source
  let newJSON = JSON.parse(JSON.stringify(json))

  // creating the rows in the table
  let html = ''
  for (let key in json) {
    const {
      searchCriteria: {
        criteria: {
          maxBuy
        }
      },
      abSettings: {
        buyPrice,
        sellPrice
      }
    } = json[key]
    const rowData = {
      key,
      maxBuy,
      buyPrice,
      sellPrice
    }
    html += tableRow(rowData)
  }
  // setting rows of the tbody
  const tableBody = document.querySelector('#table tbody')
  tableBody.innerHTML = html

  // setting up input action (update)
  const inputs = document.querySelectorAll('input')
  inputs.forEach(input => {
    input.addEventListener('input', function(e) {
      // setting up received data
      const {
        target: {
          value: val,
          dataset
        }
      } = e
      const [key, dataid] = dataset['updateid'].split(',')

      // the newJSON is updated here
      if (dataid === 'maxBuy') {
        newJSON[key].searchCriteria.criteria.maxBuy = val
      } else {
        newJSON[key].abSettings[dataid] = val
      }
    })
  })

  // modal handling
  const backdrop = document.getElementById('backdrop')
  backdrop.addEventListener('click', function() {
    this.classList.toggle('show')
  })
  const modal = document.getElementById('modal')
  modal.addEventListener('click', function(e) {
    e.stopPropagation()
  })

  // create new object & display it in the modal
  const btnGetNewObject = document.getElementById('getNewObject')
  btnGetNewObject.addEventListener('click', function(e) {
    const tocopy = document.getElementById('tocopy')
    tocopy.value = JSON.stringify(writeObject(newJSON))
    backdrop.classList.add('show')
  })
})(getJSON(d));
table {
  border-collapse: collapse;
}

table,
table tr th,
table tr td {
  border: 1px solid black;
}

table tr th,
table tr td {
  padding: 8px 16px;
}

#backdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.25);
  z-index: 10;
  display: none;
  justify-content: center;
  align-items: center;
  cursor: pointer;
}

#backdrop.show {
  display: flex;
}

#modal {
  padding: 16px;
  background: white;
}
<button id="getNewObject">GET NEW OBJECT</button><br /><br />
<hr />
<table id="table">
  <thead>
    <th>
      KEY
    </th>
    <th>
      VARIABLE
    </th>
    <th>
      SOURCE VALUE
    </th>
    <th>
      NEW VALUE
    </th>
  </thead>
  <tbody>
  </tbody>
</table>
<div id="backdrop">
  <div id="modal">
    <textarea id="tocopy" rows="10" cols="30"></textarea>
  </div>
</div>

【讨论】:

  • 非常感谢,这正是我想要的。看起来这完全超出了我的想象,因为我什至不知道如何在本地运行它以使其工作。我想我有很多功课!
  • @OliverMulder 您可以将其粘贴到 HTML 中(本地)或创建 JsFiddle/Codepen sn-p 并在您想要运行它时更改输入。我很高兴能帮上忙!
  • 是的,谢谢,我想通了!这绝对是您放在一起的上帝的礼物。
  • @OliverMulder 有很多项目可能会变慢。与 Vue 应用程序相同的是,它更短、更快——只是不想用框架为您复杂化:)
  • 哦,我真的很高兴能了解更多关于这一切的信息。是否有一些文档可以链接我阅读?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2014-05-12
  • 2019-12-16
  • 2011-10-26
  • 2022-11-14
相关资源
最近更新 更多