2013-08-19 41 views
5

下面的代碼打印:什麼是測試解析的json地圖是否相等的好方法?

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和分析兩個等價的對象,將它們存儲在一個組,希望他們不會複製。情況並非如此,這似乎是因爲前兩行(意外?)導致錯誤。假設每個都是JSON.parse()的結果,正確比較兩個Map對象的有效方法是什麼?

回答

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字符串。由於我很快就放棄了,我沒有代碼,也不知道它是否真的有效,但值得一試。

0

從unittest使用的匹配器庫將執行此操作。

4

的推薦方法比較JSON地圖或列表,可能是嵌套,平等是通過使用從以下包

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?

相關問題