测试解析的json映射是否相等的好方法是什么?

时间:2013-08-19 20:22:32

标签: dart

以下代码打印:

false
false
true
{{a: b}, {a: b}}

import "dart:json" as JSON;

main() {
  print(JSON.parse('{ "a" : "b" }') == JSON.parse('{ "a" : "b" }'));
  print({ "a" : "b" } == { "a" : "b" });
  print({ "a" : "b" }.toString() == { "a" : "b" }.toString());
  Set s = new Set();
  s.add(JSON.parse('{ "a" : "b" }'));
  s.add(JSON.parse('{ "a" : "b" }'));
  print(s);
}

我正在使用json并解析两个等效对象,将它们存储在Set中,希望它们不会被复制。情况并非如此,似乎是因为前两行(意外?)导致错误。正确比较两个Map对象的有效方法是什么,假设每个都是JSON.parse()?

的结果

4 个答案:

答案 0 :(得分:4)

比较 JSON映射或列表(可能是嵌套)是否相等的推荐方法是使用以下包中的Equality类

import 'package:collection/equality.dart';

如,

Function eq = const DeepCollectionEquality().equals;
var json1 = JSON.parse('{ "a" : 1, "b" : 2 }');
var json2 = JSON.parse('{ "b" : 2, "a" : 1 }');
print(eq(json1, json2)); // => true

有关详细信息,请参阅此答案,其中讨论了一些不同的平等类:How can I compare Lists for equality in Dart?

答案 1 :(得分:3)

这是一个很难的,因为JSON对象只是列表和num,String,bool和Null的映射。在Dart中测试地图和平等列表仍然是一个问题,请参阅https://code.google.com/p/dart/issues/detail?id=2217

<强>更新

此答案不再有效,请参阅答案@Patrice_Chalin

答案 2 :(得分:2)

实际上这很难,因为地图和列表上的==运算符并不真正比较键/值/元素。

根据您的使用情况,您可能需要编写实用程序方法。我曾经写过这个快速而肮脏的功能:

bool mapsEqual(Map m1, Map m2) {
    Iterable k1 = m1.keys;
    Iterable k2 = m2.keys;
    // Compare m1 to m2
    if(k1.length!=k2.length) return false;
    for(dynamic o in k1) {
        if(!k2.contains(o)) return false;
        if(m1[o] is Map) {
            if(!(m2[o] is Map)) return false;
            if(!mapsEqual(m1[o], m2[o])) return false;
        } else {
            if(m1[o] != m2[o]) return false;
        }
    }
    return true;
}

请注意,虽然它处理嵌套的JSON对象,但只要涉及嵌套列表,它就会始终返回false。如果要使用此方法,可能需要添加用于处理此问题的代码。

我曾经开始的另一种方法是为Map和List编写包装器(实现Map / List以正常使用它)并覆盖operator==,然后使用JsonParser和JsonListener来解析使用这些包装器的JSON字符串。由于我很快就抛弃了它,我没有代码,也不知道它是否真的有效,但它值得一试。

答案 3 :(得分:0)

使用unittest的matcher库将执行此操作。