2016-06-14 3 views
-1

У меня есть вложенное общественный класс KeyCountMapСортировка пользовательский словарь класс C#

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... 
} 

перебирать значения в карте в порядке значений убывания, если мы будем использовать 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() метод (не используется здесь) для сортировки?

EDIT

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; 
    } 
} 
+0

Словари не гарантированно вернуть элементы в том порядке, в котором они были вставлены, поэтому то, что вы пытаетесь сделать там, вероятно, не сработает. –

+0

Итак, как решить эту проблему, например, сортировку словаря? – maliks

+0

Пожалуйста, посмотрите на '' SortedDictionary

ответ

2

Словари (HashTables) не имеют порядок. Попытка заказать хешсет, контролируя порядок вставки, просто не будет работать. Если вы хотите заказать, не используйте словарь в качестве резервного хранилища.

+0

Посмотрите на 'SortedSet' (https://msdn.microsoft.com/en-us/library/dd412070(v=vs.110).aspx). – Dejan

+0

@Taufel Ну, что вам нужно? Вам нужен «Словарь», используйте его. Вам нужен «Список», используйте его. Я предлагаю вам ознакомиться с различиями между ними. Словарь не является списком. –

+0

Если вы видите, входной параметр метода SortMapByDescendValue() 'имеет тип' KeyCountMap ', тогда как сортировка выполняется с помощью' List', поэтому проблема является параметром типа 'KeyCountMap ', который является классом используя 'Dictionary' – maliks

0

Если вы хотите ПОСТОЯННО отсортированный словарь, вы можете попробовать реализовать сортировку с SortedDictionary<K,V>:

// 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); 
    }) 
); 

EDIT: если вы хотите представлять словарь упорядоченный по значению, лучший способ это ИМХО чтобы значения сравнимы

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<K, V>)

+0

Для вашего уведомления здесь' MutableInt' является определяемым пользователем классом, обновленным выше – maliks

+0

@Taufel: Я вижу, я предположил, что 'MutableInt' является своего рода * целым числом *, и именно поэтому * сопоставимы * друг с другом, другими словами 'MutableInt' реализует' IComparable ' –

+0

Но для меня не получается, что то, что вы дали в ваш ответ, это метод вместо 'SortMapByDescendValue()' или что еще это такое? – maliks

Смежные вопросы