2013-03-25 26 views
5

Có tương tự .NET của defaultdict của Python không? Tôi thấy hữu ích khi viết mã ngắn, ví dụ: tần số đếm:Tương tự với defaultdict của Python?

>>> words = "to be or not to be".split() 
>>> print words 
['to', 'be', 'or', 'not', 'to', 'be'] 
>>> from collections import defaultdict 
>>> frequencies = defaultdict(int) 
>>> for word in words: 
...  frequencies[word] += 1 
... 
>>> print frequencies 
defaultdict(<type 'int'>, {'not': 1, 'to': 2, 'or': 1, 'be': 2}) 

Vì vậy, lý tưởng trong C# Tôi có thể viết:

var frequencies = new DefaultDictionary<string,int>(() => 0); 
foreach(string word in words) 
{ 
    frequencies[word] += 1 
} 
+2

nào 'defaultdict' làm gì ? Tôi không quen với python. Chỉnh sửa: Nó chỉ là một từ điển có giá trị mặc định cho các phím. Bạn có thể phân lớp 'Dictionary' và thực hiện chức năng. – Romoku

+1

Câu trả lời của Jon Skeet có thể giúp: http://stackoverflow.com/a/2601501/1786606. – Vladimir

Trả lời

4

Tôi không nghĩ rằng có một tương đương, nhưng với ví dụ của bạn, bạn có thể làm điều này với LINQ:

var words = new List<string>{ "One", "Two", "Three", "One" }; 
var frequencies = words.GroupBy (w => w).ToDictionary (w => w.Key, w => w.Count()); 
3

Điều gì đó để giúp bạn bắt đầu. Về cơ bản tôi chỉ thay đổi chỉ mục this. Vì tôi không biết chức năng đầy đủ của số defaultdict của python, tôi không thể cải thiện thêm nữa. Ví dụ của bạn sẽ làm việc.

public class DefaultDictionary<TKey, TValue> : IDictionary<TKey,TValue> 
{ 
    private readonly Func<TValue> _defaultSelector; 
    private readonly Dictionary<TKey, TValue> _values = new Dictionary<TKey, TValue>(); 

    public DefaultDictionary(Func<TValue> defaultSelector) 
    { 
     _defaultSelector = defaultSelector; 
    } 

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() 
    { 
     return _values.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public void Add(KeyValuePair<TKey, TValue> item) 
    { 
     ((IDictionary<TKey,TValue>)_values).Add(item); 
    } 

    public void Clear() 
    { 
     _values.Clear(); 
    } 

    public bool Contains(KeyValuePair<TKey, TValue> item) 
    { 
     return ((IDictionary<TKey,TValue>)_values).Contains(item); 
    } 

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) 
    { 
     ((IDictionary<TKey, TValue>)_values).CopyTo(array, arrayIndex); 
    } 

    public bool Remove(KeyValuePair<TKey, TValue> item) 
    { 
     return ((IDictionary<TKey, TValue>)_values).Remove(item); 
    } 

    public int Count { get { return _values.Count; } } 
    public bool IsReadOnly { get { return ((IDictionary<TKey, TValue>) _values).IsReadOnly; } } 
    public bool ContainsKey(TKey key) 
    { 
     return _values.ContainsKey(key); 
    } 

    public void Add(TKey key, TValue value) 
    { 
     _values.Add(key, value); 
    } 

    public bool Remove(TKey key) 
    { 
     return _values.Remove(key); 
    } 

    public bool TryGetValue(TKey key, out TValue value) 
    { 
     return _values.TryGetValue(key, out value); 
    } 

    public TValue this[TKey key] 
    { 
     get 
     { 
      if (!_values.ContainsKey(key)) 
      { 
       _values.Add(key, _defaultSelector()); 
      } 
      return _values[key]; 
     } 
     set 
     { 
      if(!_values.ContainsKey(key)) 
      { 
       _values.Add(key, _defaultSelector()); 
      } 
      _values[key] = value; 
     } 
    } 

    public ICollection<TKey> Keys { get { return _values.Keys; } } 
    public ICollection<TValue> Values { get { return _values.Values; } } 

    public Dictionary<TKey, TValue> ToDictionary() 
    { 
     return new Dictionary<TKey, TValue>(_values); 
    } 
} 
3

Dưới đây là một việc thực hiện đơn giản:

public class DefaultDictionary<TKey, TValue> : Dictionary<TKey, TValue> where TValue : new() 
{ 
    public new TValue this[TKey key] 
    { 
     get 
     { 
      TValue val; 
      if (!TryGetValue(key, out val)) 
      { 
       val = new TValue(); 
       Add(key, val); 
      } 
      return val; 
     } 
     set { base[key] = value; } 
    } 
} 

Và làm thế nào bạn sẽ sử dụng nó:

var dict = new DefaultDictionary<string, int>(); 
Debug.WriteLine(dict["foo"]); // prints "0" 
dict["bar"] = 5; 
Debug.WriteLine(dict["bar"]); // prints "5" 

Hoặc như thế này:

var dict = new DefaultDictionary<string, List<int>>(); 
dict["foo"].Add(1); 
dict["foo"].Add(2); 
dict["foo"].Add(3); 
Các vấn đề liên quan