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

时间:2019-07-12 14:34:47

标签: javascript json multidimensional-array

我正在尝试将多级JSON简化为唯一记录的数组。

这是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

2 个答案:

答案 0 :(得分:1)

您可以创建一个自定义函数来比较嵌套对象。

  • 创建一个将包含两个对象的函数。
  • 遍历对象的键。检查两个对象的相同键是否不同,然后返回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)

答案 1 :(得分:1)

使用字符串化方法,可以使用数组的一个循环并按需添加来减少步骤,并在添加之前检查是否已存在该项。

但是,如果任何属性与数组中其他元素的顺序不同,则使用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)

如果您有足够多的这类操作,建议您使用lodash.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>