目录
介绍
兴趣点
我的CSV列数据中有些不符合列名顺序。将数据字典枚举为KeyValuePair不会以任何特定顺序返回数据,并且使用System.Collection.Specialized的OrderedDictionary很麻烦。因此,我创建了自己的有序词典,称为ListDictionary,本技巧文章中对此进行了讨论。
- 下载源2.7 KB
我一直在使用CSV脚本,将List列名称和Dictionary列数据暂存起来。我意识到我的某些列数据不符合列名顺序。事实证明,将数据Dictionary枚举为KeyValuePair 并不会以任何特定的顺序返回数据。所以我需要一本有序的字典。
网上的文章说使用System.Collection.Specialized的OrderedDictionary。太好了,它是可排序的!但这不是“通用”的,而是对象到对象的,需要在整个地方进行映射以实现轻载。
所以我说:“不管了!” 并决定写点东西做这份工作。它的内部可以快速查找Dictionary,而List内部则可以使事情井井有条。我叫它ListDictionary。我不是为处理大量数据而设计的,而是着眼于有序的行为,希望它对您有好处。
using System;
using System.Collections.Generic;
using System.Linq;
namespace metastrings
{
public class ListDictionary where K : IComparable
{
public List Entries => m_list;
public IEnumerable Keys => m_list.Select(kvp => kvp.Key);
public IEnumerable 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(key, val);
added = true;
break;
}
}
}
if (!added)
m_list.Add(new KeyValuePair(key, val));
m_dict[key] = val;
}
private List m_list = new List();
private Dictionary m_dict = new Dictionary();
}
}
没什么。尚未完全完善,我只是添加了所需的内容和一些单元测试:
ListDictionary dict = new ListDictionary();
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"]);
兴趣点
必须使用带有get和set的索引器。必须使用IComparable。用OrderedDictionary足够恨它。人们在.NET 2.0之前做了什么?