代码之家  ›  专栏  ›  技术社区  ›  cmill

将多级JSON简化为唯一记录数组

  •  0
  • cmill  · 技术社区  · 6 年前

    我试图将多级JSON简化为一个唯一记录数组。

    { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null }

    我发现的每个例子都演示了如何减少一个简单的字符串/数字数组或一个单一级别的JSON对象。

    下面是我的工作代码,它通过3个步骤找到唯一的记录并以所需的JSON格式输出。

    感谢您的帮助和理解。

    //Array containing duplicates
    var array = [
      { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null },	//duplicate
      { "id": { "v": "982W:813", "f": "813" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:813", "f": "813" }, "parent": "982W", "size": null },	//duplicate
      { "id": { "v": "982W:831", "f": "831" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:831", "f": "831" }, "parent": "982W", "size": null }	//duplicate
    ];
    //console.log('array', array);
        
        
    //Stringify the array 
    var array_stringify = [];
    for (var i = 0; i < array.length; i++) {
      array_stringify.push(JSON.stringify(array[i]));
    }
    //console.log('array_stringify', array_stringify);
        	
    //Create set from the array to remove duplicates and convert into an array of strings
    var array_set = new Set(array_stringify);
    var array_arryFromSet = Array.from(array_set);
    //console.log('array_arryFromSet', array_arryFromSet);
    
    //Parse each string into the original JSON format
    var array_parse = [];
    var push_value;
    for (var i = 0; i < array_arryFromSet.length; i++) {
      push_value = JSON.parse(array_arryFromSet[i]);
      array_parse.push(push_value);
    }
    console.log('array_parse', array_parse);
        
    /* array_parse RESULT            
    [
      { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:813", "f": "813" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:831", "f": "831" }, "parent": "982W", "size": null }
    ]    
    */

    enter image description here

    1 回复  |  直到 6 年前
        1
  •  1
  •   charlietfl    6 年前

    使用stringify方法,您可以通过使用数组的一个循环并在执行时添加到set来减少步骤,在添加项之前检查该项是否已经存在。

    使用 JSON.stringify() 但是,如果任何属性与数组中其他元素的顺序不同,并且通常不是推荐的方法,则该方法将不起作用。使用 “深度相等” 递归函数更安全

    var array = [
      { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null },	//duplicate
      { "id": { "v": "982W:813", "f": "813" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:813", "f": "813" }, "parent": "982W", "size": null },	//duplicate
      { "id": { "v": "982W:831", "f": "831" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:831", "f": "831" }, "parent": "982W", "size": null }	//duplicate
    ];
    
    
    var set = new Set()
    
    var res = array.reduce((a, c)=>{
       var str = JSON.stringify(c)
       if(!set.has(str)){
           set.add(str)
           return a.concat(c);
       }   
       return a
    },[])
    
    console.log(res)

    如果您有足够的此类操作,建议您使用洛达斯.js这将允许你在一个非常简单的一行中完成

    var array = [
      { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null },	//duplicate
      { "id": { "v": "982W:813", "f": "813" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:813", "f": "813" }, "parent": "982W", "size": null },	//duplicate
      { "id": { "v": "982W:831", "f": "831" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:831", "f": "831" }, "parent": "982W", "size": null }	//duplicate
    ];
    
    
    var res = _.uniqWith(array, _.isEqual);
    
    console.log(res)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.14/lodash.min.js"></script>
        2
  •  1
  •   Maheer Ali    6 年前

    • 创建一个包含两个对象的函数。
    • 遍历对象的键。检查两个对象的同一键是否不相同,然后返回 false
    • 检查这些值是否是其他对象,然后对这两个值递归调用函数。
    • true
    • 然后使用 filter() some() 删除重复项。

    const isObj = a => a && typeof a === "object"
    
    function compare(obj1,obj2){
      if(Object.keys(obj1).length !== Object.keys(obj2).length) return false;
      for(let k in obj1){
        if([obj1[k], obj2[k]].every(isObj)){
          if(!compare(obj1[k],obj2[k])) return false;
        }
        else{
          if(obj1[k] !== obj2[k]) return false;
        }
      }
      return true;
    }
    
    
    
    var array = [
      { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:811", "f": "811" }, "parent": "982W", "size": null },	//duplicate
      { "id": { "v": "982W:813", "f": "813" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:813", "f": "813" }, "parent": "982W", "size": null },	//duplicate
      { "id": { "v": "982W:831", "f": "831" }, "parent": "982W", "size": null },
      { "id": { "v": "982W:831", "f": "831" }, "parent": "982W", "size": null }	//duplicate
    ];
    
    let res = array.filter((x,i) => array.slice(i+1).every(a => !compare(x,a)))
    console.log(res)