2015-05-01 24 views
1

是否可以按照它們在源文檔中出現的相同順序訪問映射的鍵?即如果我有這個簡單的文檔:我可以依次讀取YamlDotNet映射嗎?

values: 
    first: something1 
    second: something2 
    third: something3 

然後我就能夠拿到鑰匙的序列中的原始順序:第一,第二,第三]

回答

4

實現此目的的一種方法是使用RepresentationModel API。它允許獲得YAML文檔的底層結構緊密匹配的表示:

var stream = new YamlStream(); 
stream.Load(new StringReader(yaml)); 

var document = stream.Documents.First(); 

var rootMapping = (YamlMappingNode)document.RootNode; 
var valuesMapping = (YamlMappingNode)rootMapping.Children[new YamlScalarNode("values")]; 

foreach(var tuple in valuesMapping.Children) 
{ 
    Console.WriteLine("{0} => {1}", tuple.Key, tuple.Value); 
} 

這種方法的缺點是,你需要「手動」解析文檔。另一種方法是使用序列化,並使用保留排序的類型。我不知道任何現成的使用實施IDictionary<TKey, TValue>具有此特徵的,但如果你不關心性能高,它是相當簡單的實現:

// NB: This is a minimal implementation that is intended for demonstration purposes. 
//  Most of the methods are not implemented, and the ones that are are not efficient. 
public class OrderPreservingDictionary<TKey, TValue> 
    : List<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue> 
{ 
    public void Add(TKey key, TValue value) 
    { 
     Add(new KeyValuePair<TKey, TValue>(key, value)); 
    } 

    public bool ContainsKey(TKey key) 
    { 
     throw new NotImplementedException(); 
    } 

    public ICollection<TKey> Keys 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public bool Remove(TKey key) 
    { 
     throw new NotImplementedException(); 
    } 

    public bool TryGetValue(TKey key, out TValue value) 
    { 
     throw new NotImplementedException(); 
    } 

    public ICollection<TValue> Values 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public TValue this[TKey key] 
    { 
     get 
     { 
      return this.First(e => e.Key.Equals(key)).Value; 
     } 
     set 
     { 
      Add(key, value); 
     } 
    } 
} 

一旦你有了這樣的容器,你可以採取Serialization API的優勢來解析文檔:

var deserializer = new Deserializer(); 
var result = deserializer.Deserialize<Dictionary<string, OrderPreservingDictionary<string, string>>>(new StringReader(yaml)); 

foreach(var tuple in result["values"]) 
{ 
    Console.WriteLine("{0} => {1}", tuple.Key, tuple.Value); 
} 

You can see a fully working example in this fiddle

+0

只是爲人們尋找這與無意推行有序字典:我覺得這個[TKEY的鍵]被錯誤地執行,你守首先檢查密鑰是否存在,除非你想重複。 另請參閱[this](https://msdn.microsoft.com/pl-pl/library/system.collections.specialized.ordereddictionary(v = vs.110).aspx) – MaLiN2223

相關問題