javascript - 如何在 Javascript 中动态更改 JSON 键(包括其子键)?

标签 javascript node.js mongodb nosql key-value

我正在从一个端点获取一个 JSON,我想将它插入到我的 mongoDB 数据库中。问题是来自 JSON 的一些键有一个“.”。在其中,mongoDB 在假设插入这种键时会抛出错误,例如:

object: {
"DR.No": 1
}

这是我正在获取的实际端点: https://api.opensea.io/api/v1/asset_contracts/ 它是一个对象数组,其中一些具有“特征”对象,有时具有这些键值(Ctrl+F 并搜索“DR.”以了解我的意思)。

当我删除此部分时,一切正常。

app.post("/something", (req, res, next) => {
   fetch("https://api.opensea.io/api/v1/asset_contracts/")
  .then(r => r.json())
  .then(data => {
    for (let i = 0; i < data.length; i++) {
      delete  data[i].traits; //works when deleted, I need it though
      ...

我需要特征部分。我想用逗号替换所有的点。 因此,我需要动态更改 key 及其子 key 的名称。

类似的问题更侧重于如何包含 .加入 mongoDB 而不是动态更改 key (这是我想要的解决方案)

最佳答案

一种可能的方法是将 key 重新写入一个新对象,如下所示:

let obj = {};
let o = { "DR.No":1, "foo": 2 };
let keys = Object.keys(o);
for(let i = 0;i < keys.length;i++) {  
    let key = keys[i];
    obj[key.replace(".",",")] = o[key] 
}
JSON.stringify(obj,null,2)

"{
  "DR,No": 1,
  "foo": 2
}"

或者如果有很多点:

let obj = {};
let o = { "DR.No.Blah.Dots.ToMany":1, "Weird.Dots.In.Keys": 2 };
let keys = Object.keys(o);
for(let i = 0;i < keys.length;i++) {  
    let key = keys[i];
    let originalKey = key;
    key = key.split(".").join(",");
    obj[key] = o[originalKey] 
}
JSON.stringify(obj,null,2)
"{
  "DR,No,Blah,Dots,ToMany": 1,
  "Weird,Dots,In,Keys": 2
}"

如果您希望键中没有标点符号,请去掉逗号....

....在此处回答您的评论是一种可行的方法。从您问题中的 json 数据中抽取样本:

 var data = [
    {
        "address": "0xde083e40fe84835cbbd6c69f6595cae1e85551dc",
        "name": "Ledger Legend Cards",
        "symbol": "LLC",
        "image_url": "https://storage.googleapis.com/opensea-static/ledgerlegends-logo.png",
        "featured_image_url": null,
        "featured": false,
        "description": "Ledger Legends is an early access collectible card game built on the Ethereum platform. It uses the new ERC721 non-fungible token standard to track its cards. Using this standard makes it easy for the cards to integrate into the wider Ethereum ecosystem, like exchanges and wallets. Being a card game that is built using smart contracts you know that your cards will always be owned by you and can never be taken away by anyone unlike centralized games such as Hearthstone.",
        "external_link": "https://ledgerlegends.com/",
        "wiki_link": null,
        "stats": {
            "seven_day_volume": 0,
            "seven_day_change": 0,
            "total_volume": 0,
            "count": 282,
            "num_owners": 54,
            "market_cap": 0,
            "average_price": 0,
            "items_sold": 0
        },
        "traits": [
            {
                "FN.RA.NA": "Value A",
                "RR.TT.DD": "Value B",
            },
            {
                "FN.RA.NA": "Value A",
                "RR.TT.DD": "Value B",
            },
            {
                "FN.RA.NA": "Value A",
                "RR.TT.DD": "Value B",
            },
            {
                "FN.RA.NA": "Value A",
                "RR.TT.DD": "Value B",
                "MORE.MORE.MORE": [
                    {
                        "FN.RA.NA": "Value A",
                        "RR.TT.DD": "Value B",
                    },
                    {
                        "FN.RA.NA": "Value A",
                        "RR.TT.DD": "Value B",
                    },
                    {
                        "FN.RA.NA": "Value A",
                        "RR.TT.DD": "Value B",
                    },
                    {
                        "FN.RA.NA": "Value A",
                        "RR.TT.DD": "Value B",
                    }
                ]
            }
        ],
        "hidden": true,
        "nft_version": "1.0",
        "schema_name": "ERC721",
        "display_data": {
            "images": [
                "https://ledgerlegends.com/img/monster.png",
                "https://ledgerlegends.com/img/monster.png",
                "https://ledgerlegends.com/img/monster.png",
                "https://ledgerlegends.com/img/monster.png",
                "https://ledgerlegends.com/img/monster.png",
                "https://ledgerlegends.com/img/monster.png"
            ]
        },
        "short_description": null,
        "total_supply": null,
        "owner": null,
        "buyer_fee_basis_points": 0,
        "seller_fee_basis_points": 250
    }

];

//is it an object
function isObject(o) {
    return Object.prototype.toString.call(o) === "[object Object]";
}
//is it an array
function isArray(o) {
    return Array.isArray(o);
}
//clean the keys and take advantage of the reference to the original 
    //object to re write and replace the keys and their values
    function cleanKeys(o) {
        var keys = Object.keys(o);
        for (var i = 0; i < keys.length; i++) {
            var key = keys[i];
            var toCheck = o[key];
            var originalKey = key;
            //if there is a dot in the key
            //re write it and replace it
            if (key.indexOf('.') > -1) {
                key = key.split(".").join(",");
                o[key] = o[originalKey];
                delete o[originalKey];
            }
            if (isArray(toCheck) || isObject(toCheck)) {
                removeDots(toCheck);
            }
        }
    }
//a somewhat recursive function with bits broken out for readability 
function removeDots(obj) {
    switch (Object.prototype.toString.call(obj)) {
        case "[object Array]":
            for (var i = 0; i < obj.length; i++) {
                var o = obj[i];
                if (isArray(o)) {
                    removeDots(obj);
                } else {
                    cleanKeys(o);
                }
            }
            break;
        case "[object Object]":
            cleanKeys(obj);
            break;
    }
}
removeDots(data);


console.log(JSON.stringify(data, null, 2));



 [
  {
    "address": "0xde083e40fe84835cbbd6c69f6595cae1e85551dc",
    "name": "Ledger Legend Cards",
    "symbol": "LLC",
    "image_url": "https://storage.googleapis.com/opensea-static/ledgerlegends-logo.png",
    "featured_image_url": null,
    "featured": false,
    "description": "Ledger Legends is an early access collectible card game built on the Ethereum platform. It uses the new ERC721 non-fungible token standard to track its cards. Using this standard makes it easy for the cards to integrate into the wider Ethereum ecosystem, like exchanges and wallets. Being a card game that is built using smart contracts you know that your cards will always be owned by you and can never be taken away by anyone unlike centralized games such as Hearthstone.",
    "external_link": "https://ledgerlegends.com/",
    "wiki_link": null,
    "stats": {
      "seven_day_volume": 0,
      "seven_day_change": 0,
      "total_volume": 0,
      "count": 282,
      "num_owners": 54,
      "market_cap": 0,
      "average_price": 0,
      "items_sold": 0
    },
    "traits": [
      {
        "FN,RA,NA": "Value A",
        "RR,TT,DD": "Value B"
      },
      {
        "FN,RA,NA": "Value A",
        "RR,TT,DD": "Value B"
      },
      {
        "FN,RA,NA": "Value A",
        "RR,TT,DD": "Value B"
      },
      {
        "FN,RA,NA": "Value A",
        "RR,TT,DD": "Value B",
        "MORE,MORE,MORE": [
          {
            "FN,RA,NA": "Value A",
            "RR,TT,DD": "Value B"
          },
          {
            "FN,RA,NA": "Value A",
            "RR,TT,DD": "Value B"
          },
          {
            "FN,RA,NA": "Value A",
            "RR,TT,DD": "Value B"
          },
          {
            "FN,RA,NA": "Value A",
            "RR,TT,DD": "Value B"
          }
        ]
      }
    ],
    "hidden": true,
    "nft_version": "1.0",
    "schema_name": "ERC721",
    "display_data": {
      "images": [
        "https://ledgerlegends.com/img/monster.png",
        "https://ledgerlegends.com/img/monster.png",
        "https://ledgerlegends.com/img/monster.png",
        "https://ledgerlegends.com/img/monster.png",
        "https://ledgerlegends.com/img/monster.png",
        "https://ledgerlegends.com/img/monster.png"
      ]
    },
    "short_description": null,
    "total_supply": null,
    "owner": null,
    "buyer_fee_basis_points": 0,
    "seller_fee_basis_points": 250
  }
]

关于javascript - 如何在 Javascript 中动态更改 JSON 键(包括其子键)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53877857/

相关文章:

javascript - 在 Node/Express 中使用 Pug 模板引擎进行动态模板渲染

mysql - 具有多个数据库(mongodb、mysql)的 ruby​​ on rails

javascript - 无法绑定(bind)到 'mdMenuTriggerFor',因为它不是 'button' 的已知属性

JavaScript:打印完整网页时,IE 似乎没有在页面上打印 iFrame 的内容

javascript - LoopbackJS 获取经过身份验证的 UserId 以针对模型存储而不通过 API 公开它

node.js - 如何在 Mongoose 查询中使用 if 语句?

javascript - MongoDB:在数组中查询索引 n 处的 'true' 值

javascript - 使用 lodash 的数组中最频繁的项

javascript - JQuery .html() 在 Chrome 中有时表现得很奇怪

javascript - 使用 Promise.all 避免唯一错误 E11000