在node.js中比较两个JSON格式的对象数据的最有效方法是什么?
这些对象不包含“undefined”或函数,它们的原型是Object
。
我听说如果在node.js
中有JSON,那么有很好的支持答案 0 :(得分:5)
友!如果我不理解某些事情,或者用错误的术语解释问题,我真的很抱歉。我想做的就是比较两个 JSON标准化数据的相等性,如下所示:
{"skip":0, "limit":7, "arr": [1682, 439, {"x":2, arr:[]}] }
{"skip":0, "limit":7, "arr": [1682, 450, "a", ["something"] }
我100%确定这些数据中没有任何功能Date
,null
或undefined
等。我想说我不想在最常见的情况下比较JavaScript对象(复杂的原型,循环链接和所有这些东西)。这些数据的原型将是Object
。我也很确定很多熟练的程序员在我面前回答了这个问题。
我缺少的主要是我不知道如何正确解释我的问题。请随时编辑我的帖子。
我的回答:
第一种方式:效率低但可靠。您可以修改a generic method like this,这样就不会浪费时间查找函数和undefined
。请注意,泛型方法会对对象进行三次迭代(内部有三个for .. in
循环)
第二种方式:高效但有一个限制。我发现JSON.stringify
中的JSON.stringify(data1) == JSON.stringify(data2)
非常快。有效的最快解决方案是:
{{1}}
非常重要的注意事项!据我所知,JavaScript和JSON都不会影响对象字段的顺序。但是,如果比较由对象组成的字符串,这将非常重要。在我的程序中,对象字段总是以相同的顺序创建,因此上面的代码可以工作。我没有在V8文档中搜索,但我认为我们可以依赖字段创建顺序。在其他情况下,请注意使用此方法。
在我的具体案例中,第二种方式的效率是第一种方式的10倍。
答案 1 :(得分:2)
我已经对各种技术进行了一些基准测试,下划线排在最前面:
> node nodeCompare.js
deep comparison res: true took: 418 (underscore)
hash comparison res: true took: 933
assert compare res: true took: 2025
string compare res: true took: 1679
以下是源代码:
var _ = require('underscore');
var assert = require('assert');
var crypto = require('crypto');
var large = require('./large.json');
var large2 = JSON.parse(JSON.stringify(large));
var t1 = new Date();
var hash = crypto.createHash('md5').update(JSON.stringify(large)).digest('hex');
var t2 = new Date();
var res = _.isEqual(large, large2);
var t3 = new Date();
var res2 = (hash == crypto.createHash('md5').update(JSON.stringify(large2)).digest('hex'));
var t4 = new Date();
assert.deepEqual(large, large2);
var t5 = new Date();
var res4 = JSON.stringify(large) === JSON.stringify(large2);
var t6 = new Date();
console.log("deep comparison res: "+res+" took: "+ (t3.getTime() - t2.getTime()));
console.log("hash comparison res: "+res2+" took: "+ (t4.getTime() - t3.getTime()));
console.log("assert compare res: true took: "+ (t5.getTime() - t4.getTime()));
console.log("string compare res: "+res4+" took: "+ (t6.getTime() - t5.getTime()));
答案 2 :(得分:1)
从表面上看,我相信这就是你要找的东西:
Object Comparison in JavaScript
但是,这里找到了更完整的答案:
How do you determine equality for two JavaScript objects?
这些答案分别来自2年和3年前。在发布之前搜索网站以查找您想要的问题总是一个好主意,或者更广泛地搜索Google - Google中的“javascript比较两个JSON对象”会返回很多。目前最热门的4个点击都是StackOverflow的答案。
答案 3 :(得分:1)
您可以对JSON对象使用rename / unset / set diff - https://github.com/mirek/node-rus-diff
npm install rus-diff
您的示例JSON对象:
a = {"skip":0, "limit":7, "arr": [1682, 439, {"x":2, arr:[]}] }
b = {"skip":0, "limit":7, "arr": [1682, 450, "a", ["something"]] }
var rusDiff = require('rus-diff').rusDiff
console.log(rusDiff(a, b))
...生成以下差异:
{ '$set': { 'arr.1': 450, 'arr.2': 'a', 'arr.3': [ 'something' ] } }
...这是MongoDB兼容的diff格式。
如果文档相同,rusDiff(a, b)
会返回false
。