如何在Javascript中动态更改JSON密钥(包括其子密钥)?

时间:2018-12-21 00:40:22

标签: 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
      ...

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

类似的问题更多地集中在如何包括上。而不是动态更改密钥(这是我想要的解决方案)

2 个答案:

答案 0 :(得分:1)

一种可行的方法是将密钥重新写入新对象,如下所示:

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
  }
]

答案 1 :(得分:0)

也许

data[i].traits = Object.entries(data[i].traits).reduce((memo, [key, value]) => {
  memo[key.replace(/./g, ',')] = value;
  return memo;
}, {});