如何递归处理 JSON 数据并从函数返回处理后的 JSON?

Posted

技术标签:

【中文标题】如何递归处理 JSON 数据并从函数返回处理后的 JSON?【英文标题】:How to recursively process a JSON data and return the processed JSON from a function? 【发布时间】:2018-05-13 09:52:18 【问题描述】:

我有以下带有嵌套对象的 JSON 数据。我想从此结构中删除“id”并从函数中返回更改后的 JSON。我尝试以递归方式执行此操作,但无法返回更改后的 JSON。

var jsonStr = 
"_id":"7r0c0342e",
"user":"myuser",
"project":"abcd",
"info":"DOMAIN":"Department":"profile":["workex":8,"name":"alex","id":82838,
"workex":8,"name":"smith","id":84838 ] ;


processJSON(jsonStr);

function processJSON(jsondata) 
    for (var i in jsondata) 
        var row = jsondata[i];           
        if(typeof row == "object") 
            processJSON(row);              
         else if(typeof row == 'number') 
            if(i == 'id') 
                delete jsondata[i];                    
             else                 
                continue;
            
         else 
            continue;
                      
         


console.log(jsonStr);

如何从 processJSON() 返回 JSON 的其余部分并将其保存在变量中?其次,这是递归执行它的正确方法吗?

谢谢。

【问题讨论】:

这不是 json 字符串(变量名具有误导性)。 您实际上并没有在该函数中返回任何内容,也没有改变原始 JSON 对象。所以实际上它什么也没做。另外,易卜拉欣所说的话。 ^^^ 【参考方案1】:

通过你的方法,你改变了原始对象,所以在某种程度上,你不必返回任何东西。

如果您想保留原始对象并返回更改后的副本,您首先需要制作该对象的副本,然后在其上运行您的算法。您可以制作对象的浅表副本,例如使用Object.assign:

var jsonStr = "_id":"7r0c0342e", "user":"myuser", "project":"data_mining", "info":"DOMAIN":"Department":"profile":["workex":8,"name":"alex","id":82838, "workex":8,"name":"smith","id":84838 ] ;

console.log(processJSON(jsonStr));

function processJSON(jsondata) 
  var output = Object.assign(, jsondata)

  for (var i in output) 
    var row = output[i];
    if (typeof row == "object") 
      output[i] = processJSON(row);
     else if (typeof row == 'number') 
      if (i == 'id') 
        delete output[i];
       else 
        continue;
      
     else 
      continue;
    
  

  return output;

【讨论】:

该死,你打败了我,我正在写一个非常相似的答案!除此之外,我认为您在 Underscore 等库中获得的一些过滤选项将有助于使代码更加简洁和可读。 这并不能修复深层嵌套的 id,他的问题暗示他也在尝试删除。 @Paul 你说得对。编辑我的答案来解决这个问题。【参考方案2】:

var jsonStr =
    
        "_id": "7r0c0342e",
        "user": "myuser",
        "project": "data_mining",
        "info": 
            "DOMAIN": 
                "Department": 
                    "profile": ["workex": 8, "name": "alex", "id": 82838,
                        "workex": 8, "name": "smith", "id": 84838]
                
            
        
    ;
let modifedJson = JSON.parse(JSON.stringify(jsonStr));

parseJson = function (json) 
    for (let key in json) 
        if (key === 'id') 
            delete json[key];
        
        else if (typeof json[key] === 'object') 
            parseJson(json[key])
        

    

parseJson(modifedJson)
console.log('modified',modifedJson)
console.log('original',jsonStr)

【讨论】:

【参考方案3】:

这是一个使用object-scan 修改数据的解决方案...

// const objectScan = require('object-scan');

const jsonStr =  _id: '7r0c0342e', user: 'myuser', project: 'abcd', info:  DOMAIN:  Department:  profile: [ workex: 8, name: 'alex', id: 82838 ,  workex: 8, name: 'smith', id: 84838 ]    ;

const prune = (obj) => objectScan(['**.id'], 
  rtn: 'count',
  filterFn: ( parent, property ) => 
    delete parent[property];
    return true;
  
)(obj);

console.log(prune(jsonStr)); // returns amount of deletes
// => 2
console.log(jsonStr);
// =>  _id: '7r0c0342e', user: 'myuser', project: 'abcd', info:  DOMAIN:  Department:  profile: [  workex: 8, name: 'alex' ,  workex: 8, name: 'smith'  ]    
.as-console-wrapper max-height: 100% !important; top: 0
<script src="https://bundle.run/object-scan@13.7.1"></script>

免责声明:我是object-scan的作者

...以及克隆输入并在克隆过程中省略 id 的不同解决方案...

// const objectScan = require('object-scan');

const jsonStr =  _id: '7r0c0342e', user: 'myuser', project: 'abcd', info:  DOMAIN:  Department:  profile: [ workex: 8, name: 'alex', id: 82838 ,  workex: 8, name: 'smith', id: 84838 ]    ;

const clone = (obj) => objectScan(['**', '!**.id'], 
  breakFn: ( isMatch, property, value, isLeaf, context ) => 
    if (!isMatch) 
      return;
    
    const ref = context[context.length - 1];
    if (!(property in ref)) 
      if (isLeaf) 
        ref[property] = value;
       else 
        ref[property] = Array.isArray(value) ? [] : ;
      
    
    context.push(ref[property]);
  ,
  filterFn: ( context ) => 
    context.pop();
  
)(obj, [])[0];

const r = clone(jsonStr);
console.log(jsonStr);
// =>  _id: '7r0c0342e', user: 'myuser', project: 'abcd', info:  DOMAIN:  Department:  profile: [  workex: 8, name: 'alex', id: 82838 ,  workex: 8, name: 'smith', id: 84838  ]    
console.log(r);
// =>  info:  DOMAIN:  Department:  profile: [  name: 'alex', workex: 8 ,  name: 'smith', workex: 8  ]   , project: 'abcd', user: 'myuser', _id: '7r0c0342e' 
.as-console-wrapper max-height: 100% !important; top: 0
<script src="https://bundle.run/object-scan@13.7.1"></script>

免责声明:我是object-scan的作者

【讨论】:

以上是关于如何递归处理 JSON 数据并从函数返回处理后的 JSON?的主要内容,如果未能解决你的问题,请参考以下文章

如何在js里面处理后台传来的json,并显示在页面上

快速排序算法的性能比较

快速排序算法的性能比较

数据的处理

关于eval()函数处理后台返回的json数据

RxjavaRetrofit返回json数据解析异常处理