ListDictionary:改进的OrderedDictionary

目录

介绍

兴趣点


我的CSV列数据中有些不符合列名顺序。将数据字典枚举为KeyValuePair不会以任何特定顺序返回数据,并且使用System.Collection.SpecializedOrderedDictionary很麻烦。因此,我创建了自己的有序词典,称为ListDictionary,本技巧文章中对此进行了讨论。

介绍

我一直在使用CSV脚本,将List<string>列名称和Dictionary<string, object>列数据暂存起来。我意识到我的某些列数据不符合列名顺序。事实证明,将数据Dictionary枚举为KeyValuePair 并不会以任何特定的顺序返回数据。所以我需要一本有序的字典。

网上的文章说使用System.Collection.SpecializedOrderedDictionary。太好了,它是可排序的!但这不是通用的,而是对象到对象的,需要在整个地方进行映射以实现轻载。

所以我说:不管了!” 并决定写点东西做这份工作。它的内部可以快速查找Dictionary,而List内部则可以使事情井井有条。我叫它ListDictionary。我不是为处理大量数据而设计的,而是着眼于有序的行为,希望它对您有好处。

using System;
using System.Collections.Generic;
using System.Linq;

namespace metastrings
{
   public class ListDictionary<K, V> where K : IComparable<K>
   {
     public List<KeyValuePair<K, V>> Entries => m_list;
     public IEnumerable<K> Keys => m_list.Select(kvp => kvp.Key);
     public IEnumerable<V> Values => m_list.Select(kvp => kvp.Value);

     public V this[K key]
     {
       get { return m_dict[key]; }
       set { Set(key, value); }
     }

     public int Count => m_list.Count;
     public bool ContainsKey(K key) => m_dict.ContainsKey(key);

     public K FirstKey => m_list[0].Key;

     public void Set(K key, V val)
     {
       bool added = false;
       if (m_dict.ContainsKey(key))
       {
         for (int i = 0; i < m_list.Count; ++i)
         {
           K curKey = m_list[i].Key;
           if (curKey.CompareTo(key) == 0)
           {
             m_list[i] = new KeyValuePair<K, V>(key, val);
             added = true;
             break;
           }
         }
       }

       if (!added)
         m_list.Add(new KeyValuePair<K, V>(key, val));

       m_dict[key] = val;
     }

     private List<KeyValuePair<K, V>> m_list = new List<KeyValuePair<K, V>>();
     private Dictionary<K, V> m_dict = new Dictionary<K, V>();
   }
}

没什么。尚未完全完善,我只是添加了所需的内容和一些单元测试:

ListDictionary<string, int> dict = new ListDictionary<string, int>();

dict["foo"] = 1;
dict["bar"] = 2;

Assert.AreEqual(1, dict["foo"]);
Assert.AreEqual(2, dict["bar"]);

Assert.AreEqual(2, dict.Count);

Assert.AreEqual("foo", dict.FirstKey);

Assert.AreEqual("foo", dict.Entries.First().Key);
Assert.AreEqual(1, dict.Entries.First().Value);

Assert.AreEqual("bar", dict.Entries.Last().Key);
Assert.AreEqual(2, dict.Entries.Last().Value);

Assert.IsTrue(dict.Keys.Contains("foo"));
Assert.IsTrue(dict.Values.Contains(1));

Assert.IsTrue(dict.Keys.Contains("bar"));
Assert.IsTrue(dict.Values.Contains(2));

Assert.IsTrue(dict.ContainsKey("foo"));
Assert.IsTrue(dict.ContainsKey("bar"));
Assert.IsTrue(!dict.ContainsKey("blet"));

dict["foo"] = 42;
Assert.AreEqual(42, dict["foo"]);

兴趣点

必须使用带有getset索引器。必须使用IComparable。用OrderedDictionary足够恨它。人们在.NET 2.0之前做了什么?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值