NodeJS深度嵌套json比较不区分大小写的键/值对

时间:2019-07-05 08:28:39

标签: javascript node.js json ecmascript-6 lodash

我想在NodeJS中比较两个嵌套的json,json的键位置可以更改,并且键/值比较应该不区分大小写

我正在使用深度相等的NodeJS模块,但仅适用于区分大小写的比较

let json1 = {
  "type": "NEW",
  "users": [{
    "id": "dskd3782shdsui",
    "email": "helloworld@xxxxxx.com"

  }],
  "ordered": [{
    "productId": "SHFDHS37463",
    "SKU": "ffgh"
  }]
}

let json2 = {
  "type": "NEW",
  "users": [{
    "id": "dskd3782shdsui",
    "email": "helloworld@xxxxxx.com"

  }],
  "ordered": [{
    "productId": "SHFDHS37463",
    "SKU": "ffgh"
  }]
}

var deepEqual = require('deep-equal')

console.log('==', deepEqual(
  json1,
  json2
))

上面的代码可以正常工作,但是如果我将json2电子邮件更改为helloworld@xxxxxx.COM或将电子邮件密钥更改为EMAIL,则返回false,我希望不区分大小写。

4 个答案:

答案 0 :(得分:1)

要处理字符串值之间不区分大小写的比较(这不适用于键),可以将lodash的_.isEqualWith()与自定义函数一起使用:

const obj1 = {"type":"NEW","users":[{"id":"dskd3782shdsui","email":"helloworld@xxxxxx.COM"}],"ordered":[{"productId":"SHFDHS37463","SKU":"ffgh"}]}
const obj2 = {"type":"new","users":[{"id":"dskd3782shdsui","email":"helloworld@xxxxxx.com"}],"ordered":[{"productId":"SHFDHS37463","SKU":"ffgh"}]}

const result = _.isEqualWith(
  obj1, 
  obj2, 
  (objValue, othValue) =>  _.isString(objValue) && _.isString(othValue) ?
    objValue.toLowerCase() === othValue.toLowerCase()
    :
    undefined
)

console.log('==', result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

要处理大小写不同的键,应将其标准化为小写,然后进行比较。我使用_.transform()创建了一个递归函数,该函数迭代嵌套对象,并将所有键都转换为小写。

const normaliseKeys = obj => _.transform((r, k, v) => {
  const key = _.isString(k) ? k.toLowerCase() : k;
  
  r[key] = _.isObject(v) ? normaliseKeys(v) : v;
})

const obj1 = normaliseKeys({"TYPE":"NEW","users":[{"id":"dskd3782shdsui","EMAIL":"helloworld@xxxxxx.COM"}],"ordered":[{"productId":"SHFDHS37463","SKU":"ffgh"}]})
const obj2 = normaliseKeys({"type":"new","users":[{"id":"dskd3782shdsui","email":"helloworld@xxxxxx.com"}],"ordered":[{"productId":"SHFDHS37463","SKU":"ffgh"}]})

const result = _.isEqualWith(
  obj1,
  obj2, 
  (objValue, othValue) =>  _.isString(objValue) && _.isString(othValue) ?
    objValue.toLowerCase() === othValue.toLowerCase()
    :
    undefined
)

console.log('==', result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

答案 1 :(得分:0)

如果您不介意使用https://lodash.com/docs/4.17.4#isEqualWith

var result = _.isEqualWith(json1, json2, (value1, value2, key) => { 
    console.log(value1, value2);
    //check for string and compare
});

答案 2 :(得分:0)

您可以使用:

function jsonEqual(a,b) {
    return JSON.stringify(a).toLowerCase() === JSON.stringify(b).toLowerCase();
}
console.log(jsonEqual(json1, json2))

工作示例here

答案 3 :(得分:0)

我对此有解决方案,它既适用于键/值不区分大小写,也适用于我们更改键位置的情况

var deepEqual = require('deep-equal')

function toLower(a) {
 return JSON.stringify(a).toLowerCase();
}


console.log('==', deepEqual(
    JSON.parse(toLower(json1)),
    JSON.parse(toLower(json2))
) )