这将把[1,2,3]和[3,2,1]视为相等(deep object)
因为我需要把它们之间的区别形象化:
[
{
"a":1,
"b":1
},
{
"a":1,
"b":1
}
]
and
[
{
"a":1,
"b":1
},
{
"a":"OH NO",
"b":"an insertion"
},
{
"a":1,
"b":1
}
]
所以我想看看它们的碰撞,这是剩下的:
[]
and
[
{
"a":"OH NO",
"b":"an insertion"
}
]
在我看来,这是最好的表现方式。
{添加:{…},乌利希期刊指南:{…},德尔:{…}}很难读懂
我提供了2个函数:objectcollision (obj1,obj2)和arraycollision (arr1,arr2)
console.log(ArrayCollide([1,2,3],[3,2,1]))
// false
//everything collided -> false
console.log(ArrayCollide([1],[2,1]))
// [ [], [ 2 ] ]
//1 and 1 collided, even if they are on different indices
//array of objects
const arr1 =
[
{
"a":1,
"b":1
},
{
"a":1,
"b":1
}
]
const arr2 =
[
{
"a":1,
"b":1
},
{
"a":"OH NO",
"b":"an insertion"
},
{
"a":1,
"b":1
}
]
const newArrays = ArrayCollide(arr1, arr2)
console.log(newArrays[0])
console.log(newArrays[1])
console.log('\n')
// []
// [ { a: 'OH NO', b: 'an insertion' } ]
// everything collided until this is left
//ObjectCollide
const obj1 = { a: '111', c: { q: 'no', a: '333' } }
const obj2 = { a: '111', p: 'ok', c: { a: '333' } }
ObjectCollide(obj1, obj2) //in place
console.log(obj1)
console.log(obj2)
console.log('\n')
// { c: { q: 'no' } }
// { p: 'ok', c: {} }
// obj["a"] collided and obj["c"]["a"] collided
//testing empty array
const a1 = { a: [] }
const a2 = { a: [], b: '2' }
ObjectCollide(a1, a2) //in place
console.log(a1)
console.log(a2)
console.log('\n')
// {}
// { b: '2' }
// obj["a"] collided
//DIFFERENT TYPES
const b1 = {a:true}
const b2 = {a:[1,2]}
ObjectCollide(b1,b2) //in place
console.log(b1)
console.log(b2)
// { a: true }
// { a: [ 1, 2 ] }
function ObjectCollide(obj1, obj2) {
//in place, returns true if same
// delete same
const keys = Object.keys(obj1)
const len = keys.length
let howManyDeleted = 0
for (let i = 0; i < len; i++) {
const key = keys[i]
const type1 = Array.isArray(obj1[key]) === true ? 'array' : typeof obj1[key]
const type2 = Array.isArray(obj2[key]) === true ? 'array' : typeof obj2[key]
if (type1!==type2) {
continue
}
switch (type1) {
case 'object':
if (ObjectCollide(obj1[key], obj2[key])) {
delete obj1[key]
delete obj2[key]
howManyDeleted++
}
continue
case 'array':
const newArrays = ArrayCollide(obj1[key], obj2[key])
if (newArrays) {
obj1[key] = newArrays[0]
obj2[key] = newArrays[1]
} else {
delete obj1[key]
delete obj2[key]
howManyDeleted++
}
continue
default:
//string, number, I hope it covers everything else
if (obj1[key] === obj2[key]) {
delete obj1[key]
delete obj2[key]
howManyDeleted++
}
}
}
if (howManyDeleted === len && Object.keys(obj2).length === 0) {
// return 'delete the stuff'
// same. we've deleted everything!
return true
}
}
function ArrayCollide(arr1, arr2) {
// returns [newArr1, newArr2] or false if same arrays (ignore order)
const stringifyObj = {}
const newArr1 = []
const newArr2 = []
for (let i = 0, len = arr1.length; i < len; i++) {
const value = arr1[i]
const stringified = JSON.stringify(value)
stringifyObj[stringified]
// arr = [count, ...]
const arr = stringifyObj[stringified] || (stringifyObj[stringified] = [0])
arr[0]++
arr.push(value)
}
//in 2 but not in 1
for (let i = 0, len = arr2.length; i < len; i++) {
const value = arr2[i]
const stringified = JSON.stringify(value)
const arr = stringifyObj[stringified]
if (arr === undefined) {
newArr2.push(value)
} else {
if (arr[0] === 0) {
newArr2.push(value)
} else {
arr[0]--
}
}
}
//in 1 but not in 2
stringifyKeys = Object.keys(stringifyObj)
for (let i = 0, len = stringifyKeys.length; i < len; i++) {
const arr = stringifyObj[stringifyKeys[i]]
for (let i = 1, len = arr[0] + 1; i < len; i++) {
newArr1.push(arr[i])
}
}
if (newArr1.length || newArr2.length) {
return [newArr1, newArr2]
} else {
return false
}
}
我想解决的问题是:
JSON文件不断重新排序,我想恢复JSON,如果它是等效的:像{a:1,b:2}和{b:2,a:1}
但是因为我不相信我的代码(我犯了一个错误),我想看到diff并自己检查它,我可以Ctrl+F到原始文件使用这个diff。