【问题标题】:Sorting custom class dictionary C#排序自定义类字典C#
【发布时间】:2016-10-15 03:32:49
【问题描述】:

我有一个嵌套的公共类 KeyCountMap

public KeyCountMap<T>  
{ 
   private IDictionary<T, MutableInt> map = new Dictionary<T, MutableInt>();
   public KeyCountMap()
   { }

   public KeyCountMap(Type dictionaryType)
   {
      if (!typeof(IDictionary<T, MutableInt>).IsAssignableFrom(dictionaryType))
      {
         throw new ArgumentException("Type must be a IDictionary<T, MutableInt>", "dictionaryType");
      }
      map = (IDictionary<T, MutableInt>)Activator.CreateInstance(_dictionaryType);
   }  

   public HashSet<KeyValuePair<T, MutableInt>> EntrySet()
   {
      return map.ToSet();
   }  
   //... rest of the methods...
}

为了将map中的值按值降序排列,如果我们使用Java我们可以这样写:

public static <T> KeyCountMap<T> sortMapByDescendValue(KeyCountMap<T> map) 
{
   List<Entry<T, MutableInt>> list = new LinkedList<>(map.entrySet());
   Collections.sort(list, new Comparator<Entry<T, MutableInt>>() 
   {
      @Override
      public int compare(Entry<T, MutableInt> o1, Entry<T, MutableInt> o2)  
      {
         return (-1) * (o1.getValue().get()).compareTo(o2.getValue().get());
      }
   });

   KeyCountMap<T> result = new KeyCountMap<T>();
   for (Entry<T, MutableInt> entry : list) 
   {
      result.put(entry.getKey(), entry.getValue());
   }
   return result;
}

如果我们使用C#,我们可以将方法定义为:

public static KeyCountMap<T> SortMapByDescendValue<T>(KeyCountMap<T> map)
{
   List<KeyValuePair<T, MutableInt>> list = new List<KeyValuePair<T, MutableInt>>(map.EntrySet());  
   // map.EntrySet() returns of type HashSet<KeyValuePair<T, MutableInt>>  

   list = list.OrderByDescending(x => x.Value).ToList();

   KeyCountMap<T> result = new KeyCountMap<T>();
   foreach (KeyValuePair<T, MutableInt> entry in list)
   {
      result.Put(entry.Key, entry.Value);

   }
   return result; 
}

此方法是否有效,或者是否有必要覆盖CompareTo() 方法(此处未使用)进行排序?

编辑

public class MutableInt
{
   internal int _value = 1; // note that we start at 1 since we're counting

   public void Increment()
   {
      _value++;
   }

   public void Discrement()
   {
      _value--;
   }

   public int Get()
   {
      return _value;
   }
}

【问题讨论】:

  • 字典不能保证按照插入的顺序返回项目,因此您在那里尝试执行的操作可能行不通。
  • 那么如何解决这个问题,即对字典进行排序?
  • 请看SortedDictionary&lt;K,V&gt;
  • 我在课堂上有IDictionary 而不是SortedDictionary KeyCountMap&lt;T&gt;
  • @DmitryBychenko 如果我在KeyCountMap&lt;T&gt; 类中使用SortedDictionary 而不是IDictionary 那么是否需要编写类似SortMapByDescendValue() 的方法?

标签: c# sorting dictionary


【解决方案1】:

字典(哈希表)没有顺序。试图通过控制插入顺序来排序哈希集是行不通的。如果您想订购,请不要使用字典作为您的后备存储。

【讨论】:

  • @Taufel 好吧,你需要什么?你需要一个Dictionary,使用一个。你需要一个List,使用一个。我建议您阅读两者之间的差异。字典不是列表。
  • 如果您看到,方法 SortMapByDescendValue() 的输入参数是 KeyCountMap&lt;T&gt; 类型,而排序是使用 List 完成的,所以问题是 KeyCountMap&lt;T&gt; 类型的参数是一个使用Dictionary 的类
  • @ThorstenDittmar 我的问题是另外一回事,如果你在这里阅读我的评论和.CompareTo 覆盖问题,即好像我们在 java 中使用这个就像 Collections.sort(list, new Comparator&lt;Entry&lt;T, MutableInt&gt;&gt;() 这个
【解决方案2】:

如果你想要永久排序字典,你可以尝试使用SortedDictionary&lt;K,V&gt;实现排序:

  // Please, notice ...map => new... (C# 6.0 syntax) 
  // since you can't address map in the initializator (=)
  private IDictionary<T, MutableInt> map => new SortedDictionary<T, MutableInt>(
    // You are supposed to compare keys
    Comparer<T>.Create((leftKey, rightKey) => {
      // given keys, get values
      MutableInt left = map[leftKey]; 
      MutableInt right = map[rightKey];  

      //TODO: you may want to change logic here
      // you should return any positive integer if left > right
      // negative integer if left < right
      // zero in case left == right
      // current implementation (CompareTo) assumes that 
      // MutableInt implements IComparable<MutableInt> interface
      return -left.CompareTo(right);
    })
  );

编辑:如果您想表示按值排序的字典,最好的方法是恕我直言,使值可比较

public class MutableInt: IComparable<MutableInt> 
{
  ...
  public int CompareTo(MutableInt other) 
  {
    return (null == other)
      ? 1
      : _value.CompareTo(other._value);      
  } 
  ...
}

然后使用Linq

//Notice, that you can't return sorted values as dictionary
public static IEnumerable<KeyValuePair<T, MutableInt>> SortMapByDescendValue<T>(
  KeyCountMap<T> map)
{
   return map
     .OrderByDescending(pair => pair.Value); // Value is comparable now
}

你唯一不能做的就是对标准字典进行排序(Dictionary&lt;K, V&gt;

【讨论】:

  • 请注意MutableInt 是上面更新的用户定义类
  • @Taufel:我明白了;我认为MutableInt 是某种整数,这就是为什么彼此可比,换句话说MutableInt 实现IComparable&lt;MutableInt&gt;
  • 但我无法理解您在回答中给出的内容,这是代替SortMapByDescendValue() 的方法还是其他什么?
  • @Taufel:好的,请您澄清一下,您在寻找什么? 永久排序(我当前的答案)的字典或如何表示(打印输出等)具有按某种顺序排序的值的标准字典内容?
  • 我正在寻找:将KeyCountMap&lt;T&gt; 类型的对象提供给正在进行排序的方法并返回按值下降排序的KeyCountMap&lt;T&gt; 类型,以及@987654333 的对象是什么@ 将包含,你可以看到上面给出的KeyCountMap&lt;T&gt;
猜你喜欢
  • 2012-08-15
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
相关资源
最近更新 更多