Jak se vám seřazení slovníku hodnoty?

hlasů
671

Často mám třídit slovníku, který se skládá z klíče a hodnoty, podle hodnoty. Například, mám hash slov a příslušných frekvencí, které chci na zakázku podle frekvence.

Tam je SortedList, což je dobré pro jednu hodnotu (řekněme frekvenci), který chci to map zpět ke slovu.

SortedDictionary příkazy podle klíče, nikoli hodnotou. Někteří resort s vlastní třídy , ale je zde čistější způsob, jak?

Položena 02/08/2008 v 01:40
zdroj uživatelem
V jiných jazycích...                            


18 odpovědí

hlasů
473

Použít LINQ:

Dictionary<string, int> myDict = new Dictionary<string, int>();
myDict.Add("one", 1);
myDict.Add("four", 4);
myDict.Add("two", 2);
myDict.Add("three", 3);

var sortedDict = from entry in myDict orderby entry.Value ascending select entry;

To by také umožnilo velkou flexibilitu v tom, že si můžete vybrat top 10, 20 10%, atd. Nebo pokud používáte váš index slovo frekvence pro type-ahead, můžete také zahrnout StartsWithklauzuli stejně.

Odpovězeno 04/08/2008 v 16:22
zdroj uživatelem

hlasů
459

Použití:

using System.Linq.Enumerable;
...
List<KeyValuePair<string, string>> myList = aDictionary.ToList();

myList.Sort(
    delegate(KeyValuePair<string, string> pair1,
    KeyValuePair<string, string> pair2)
    {
        return pair1.Value.CompareTo(pair2.Value);
    }
);

Vzhledem k tomu, cílíte NET 2.0 nebo vyšší, můžete zjednodušit to do syntaxe lambda - to je ekvivalent, ale kratší. Pokud cílíte na .NET 2.0 můžete použít pouze následující syntaxi pokud používáte kompilátor z Visual Studio 2008 (nebo vyšší).

var myList = aDictionary.ToList();

myList.Sort((pair1,pair2) => pair1.Value.CompareTo(pair2.Value));
Odpovězeno 02/08/2008 v 02:15
zdroj uživatelem

hlasů
179
var ordered = dict.OrderBy(x => x.Value);
Odpovězeno 11/11/2010 v 18:16
zdroj uživatelem

hlasů
148

Rozhlédl se a používat některé C # 3.0 vlastnosti můžeme udělat:

foreach (KeyValuePair<string,int> item in keywordCounts.OrderBy(key=> key.Value))
{ 
    // do something with item.Key and item.Value
}

To je nejčistší způsob, jak jsem viděl, a je podobná Ruby způsob manipulace s hash.

Odpovězeno 02/08/2008 v 01:43
zdroj uživatelem

hlasů
140

Můžete seřadit slovník hodnotou a uložit jej zpět do sebe (tak, že když ForEach nad ním hodnoty vycházejí v tomto pořadí):

dict = dict.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);

Jistě, to nemusí být správné, ale funguje to.

Odpovězeno 22/06/2011 v 11:26
zdroj uživatelem

hlasů
56

Na vysoké úrovni, nemáte jinou možnost, pak projít celý slovník a podívat se na každou hodnotu.

Možná to pomůže: http://bytes.com/forum/thread563638.html Copy / vkládání od Johna Timney:

Dictionary<string, string> s = new Dictionary<string, string>();
s.Add("1", "a Item");
s.Add("2", "c Item");
s.Add("3", "b Item");

List<KeyValuePair<string, string>> myList = new List<KeyValuePair<string, string>>(s);
myList.Sort(
    delegate(KeyValuePair<string, string> firstPair,
    KeyValuePair<string, string> nextPair)
    {
        return firstPair.Value.CompareTo(nextPair.Value);
    }
);
Odpovězeno 02/08/2008 v 01:47
zdroj uživatelem

hlasů
22

Byste nikdy nebude moci stejně seřazení slovníku. Jsou to vlastně objednal. Záruky pro slovníku je, že klíčové a hodnotu sbírky jsou iterable a hodnoty mohou být vyvolány pomocí indexu nebo klíče, ale tady není zárukou libovolném pořadí. Z tohoto důvodu budete muset získat pár název hodnota do seznamu.

Odpovězeno 19/12/2008 v 23:47
zdroj uživatelem

hlasů
16

Nemusíte řadit záznamy ve slovníku. Třída Dictionary .NET je implementován jako Hashtable - to datová struktura není sortable podle definice.

Pokud potřebujete být schopni iteraci přes své sbírce (klíčem) - musíte použít SortedDictionary, která je implementována jako strom binárního vyhledávání.

Ve vašem případě je však zdrojem struktura je irelevantní, protože je řazen podle jiném oboru. Byste ještě potřeba jej třídit podle frekvence a vložte jej do nové kolekce seřazeny podle příslušné oblasti (frekvence). Takže v této kolekci frekvence jsou klávesy a slova jsou hodnoty. Vzhledem k tomu, mnoho slov může mít stejnou frekvenci (a budete jej používat jako klíč), nelze použít ani slovník, ani SortedDictionary (oni vyžadují jedinečné klíče). To vás nechá s SortedList.

Nechápu, proč trváte na zachování odkazu na původní položky v hlavním / prvnímu slovníku.

V případě, že objekty ve své sbírce má složitější strukturu (další pole) a co jste potřebovali, aby bylo možné účinně vstoupit / třídit je pomocí několika různých oblastí as klíči - Ty by pravděpodobně potřebovat datovou strukturu vlastní, že by se skládají z hlavního úložiště, které podporuje O (1) vkládání a vyjímání (lineární seznam) a několika indexování konstrukce - slovníky / SortedDictionaries / SortedLists. Tyto indexy by použil jedno z polí ze svého komplexu třídy jako klíč a ukazatel / odkaz na LinkedListNode v lineární seznam jako hodnota.

Budete muset koordinovat vkládání a jejich snižování, aby se vaše indexy v synchronizaci s hlavním kolekce (lineární seznam) a odstranění by bylo dost drahé bych myslet. Je to podobné tomu, jak databázové indexy pracují - oni jsou fantastické pro vyhledáváními ale až se stávají přítěží, kdy je třeba provést řadu insetions a delece.

Všechny výše uvedené je pouze oprávněná, pokud se chystáte udělat nějakou look-up těžkého zpracování. Pokud budete potřebovat pouze pro výstup je jednou seřazené podle četnosti, pak byste mohl jen produkovat seznam (anonymní) tic:

var dict = new SortedDictionary<string, int>();
// ToDo: populate dict

var output = dict.OrderBy(e => e.Value).Select(e => new {frequency = e.Value, word = e.Key}).ToList();

foreach (var entry in output)
{
    Console.WriteLine("frequency:{0}, word: {1}",entry.frequency,entry.word);
}
Odpovězeno 13/12/2012 v 07:19
zdroj uživatelem

hlasů
12
Dictionary<string, string> dic= new Dictionary<string, string>();
var ordered = dic.OrderBy(x => x.Value);
return ordered.ToDictionary(t => t.Key, t => t.Value);
Odpovězeno 20/07/2015 v 11:01
zdroj uživatelem

hlasů
10

Řazení hodnoty

To ukazuje, jak třídit hodnoty ve slovníku. Vidíme konzoly programu můžete sestavit Visual Studio a spustit. Dodává klíče do slovníku a poté třídí podle jejich hodnoty. Uvědomte si, že slovník instance nejsou zpočátku řazeny v žádném případě. Používáme LINQ OrderBy klíčové slovo v příkazu dotazu.

OrderBy Clause program, který třídí slovník [C #]

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

class Program
{
    static void Main()
    {
        // Example dictionary.
        var dictionary = new Dictionary<string, int>(5);
        dictionary.Add("cat", 1);
        dictionary.Add("dog", 0);
        dictionary.Add("mouse", 5);
        dictionary.Add("eel", 3);
        dictionary.Add("programmer", 2);

        // Order by values.
        // ... Use LINQ to specify sorting by value.
        var items = from pair in dictionary
                orderby pair.Value ascending
                select pair;

        // Display results.
        foreach (KeyValuePair<string, int> pair in items)
        {
            Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
        }

        // Reverse sort.
        // ... Can be looped over in the same way as above.
        items = from pair in dictionary
        orderby pair.Value descending
        select pair;
    }
}

Výstup

dog: 0
cat: 1
programmer: 2
eel: 3
mouse: 5
Odpovězeno 20/07/2012 v 10:49
zdroj uživatelem

hlasů
10

Nebo pro zábavu, můžete použít nějaký LINQ rozšíření dobroty:

var dictionary = new Dictionary<string, int> { { "c", 3 }, { "a", 1 }, { "b", 2 } };
dictionary.OrderBy(x => x.Value)
  .ForEach(x => Console.WriteLine("{0}={1}", x.Key,x.Value));
Odpovězeno 30/06/2010 v 12:12
zdroj uživatelem

hlasů
9

Třídění SortedDictionaryseznamu vázat do ListViewřízení užitím VB.NET:

Dim MyDictionary As SortedDictionary(Of String, MyDictionaryEntry)

MyDictionaryListView.ItemsSource = MyDictionary.Values.OrderByDescending(Function(entry) entry.MyValue)

Public Class MyDictionaryEntry ' Need Property for GridViewColumn DisplayMemberBinding
    Public Property MyString As String
    Public Property MyValue As Integer
End Class

XAML:

<ListView Name="MyDictionaryListView">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Path=MyString}" Header="MyStringColumnName"></GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding Path=MyValue}" Header="MyValueColumnName"></GridViewColumn>
         </GridView>
    </ListView.View>
</ListView>
Odpovězeno 23/04/2010 v 10:36
zdroj uživatelem

hlasů
5

Ostatní odpovědi jsou dobré, pokud si vše, co chci, je mít „dočasný“ seznamu seřazeny podle hodnoty. Nicméně, pokud chcete mít slovník seřazené podle Keykteré automaticky synchronizuje s jiným slovníkem, který je seřazen podle Value, můžete použít Bijection<K1, K2>třídu .

Bijection<K1, K2> Umožňuje inicializovat sbírku se dvěma stávajícími slovníky, takže pokud chcete, aby jedna z nich bude netříděný, a chcete, aby se druhá mají být tříděny, můžete vytvořit svůj bijection s kódem, jako je

var dict = new Bijection<Key, Value>(new Dictionary<Key,Value>(), 
                               new SortedDictionary<Value,Key>());

Můžete použít dictjako každý normální slovníku (realizuje IDictionary<>), a pak volat dict.Inversezískat „inverzní“ slovník, který je seřazen podle Value.

Bijection<K1, K2>je součástí Loyc.Collections.dll , ale pokud chcete, můžete jednoduše zkopírovat zdrojový kód do vlastního projektu.

Poznámka : V případě, že existuje více klíčů se stejnou hodnotou, které nelze použít Bijection, ale můžete ručně synchronizovat mezi obyčejným Dictionary<Key,Value>a BMultiMap<Value,Key>.

Odpovězeno 26/02/2016 v 07:15
zdroj uživatelem

hlasů
5

Nejjednodušší způsob, jak získat seřazené slovník je použít vestavěný ve SortedDictionarytřídě:

//Sorts sections according to the key value stored on "sections" unsorted dictionary, which is passed as a constructor argument
System.Collections.Generic.SortedDictionary<int, string> sortedSections = null;
if (sections != null)
{
    sortedSections = new SortedDictionary<int, string>(sections);
}

sortedSections vůle obsahuje seřazený verzi sections

Odpovězeno 02/04/2010 v 23:36
zdroj uživatelem

hlasů
4

Předpokládejme, že máme slovník jako

   Dictionary<int, int> dict = new Dictionary<int, int>();
   dict.Add(21,1041);
   dict.Add(213, 1021);
   dict.Add(45, 1081);
   dict.Add(54, 1091);
   dict.Add(3425, 1061);
   sict.Add(768, 1011);

1) můžete použít temporary dictionary to store values as:

        Dictionary<int, int> dctTemp = new Dictionary<int, int>();

        foreach (KeyValuePair<int, int> pair in dict.OrderBy(key => key.Value))
        {
            dctTemp .Add(pair.Key, pair.Value);
        }
Odpovězeno 02/02/2015 v 10:46
zdroj uživatelem

hlasů
0

Ve skutečnosti v jazyce C #, slovníky dint mít sort () metody, jak jste se více zajímají o druhu hodnotami, nemůžete získat hodnoty, dokud jim poskytnout klíč, stručně řečeno, je třeba přecházet přes ně, pomocí LINQ je ORDER BY,

var items = new Dictionary<string, int>();
items.Add("cat", 0);
items.Add("dog", 20);
items.Add("bear", 100);
items.Add("lion", 50);

// Call OrderBy method here on each item and provide them the ids.
foreach (var item in items.OrderBy(k => k.Key))
{
    Console.WriteLine(item);// items are in sorted order
}

můžete udělat jeden trik,

var sortedDictByOrder = items.OrderBy(v => v.Value);

nebo

var sortedKeys = from pair in dictName
            orderby pair.Value ascending
            select pair;

jeho také záviset na tom, jaké hodnoty, které jsou ukládání,
je to single (jako string, int) nebo více (jako je seznam, pole, uživatelem definované třídě),
pokud single si můžete vytvořit seznam to pak platí druh.
-li uživatelem definované třídy, pak se tato třída musí implementovat IComparable,
ClassName: IComparable<ClassName>a přepsat compareTo(ClassName c) , protože jsou rychlejší než LINQ, a objektově orientované.

Odpovězeno 26/02/2019 v 12:39
zdroj uživatelem

hlasů
-2

Vzhledem k tomu, že máte slovník je můžete třídit přímo na hodnotách s využitím níže jednu vložku:

var x = (from c in dict orderby c.Value.Order ascending select c).ToDictionary(c => c.Key, c=>c.Value);
Odpovězeno 31/05/2014 v 23:30
zdroj uživatelem

hlasů
-2

Můžete třídit slovník hodnotou a získat výsledek ve slovníku pomocí kódu níže:

Dictionary <<string, string>> ShareUserNewCopy = 
       ShareUserCopy.OrderBy(x => x.Value).ToDictionary(pair => pair.Key,
                                                        pair => pair.Value);                                          
Odpovězeno 24/07/2012 v 13:24
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more