SortedList не сортирует по ключу - VB.NET - PullRequest
1 голос
/ 25 марта 2009

У меня есть потребность в паре ключ-значение, которую я хочу отсортировать, поэтому я решил использовать SortedList вместо HashTable.

Я добавляю данные в указанном ниже порядке в мой SortedList, который мне нужен в

     Key          | Value
     --------------------------------
 1   "700-800"    | List(Of Object)
 2   "900-1000"   | List(Of Object)
 3   "1100-1200"  | List(Of Object)
 4   "1700-1800"  | List(Of Object)
 5   "1900-2000"  | List(Of Object)

Ключ представляет собой строку, а значение - список объектов. Ключ представляет временной интервал, который объединен из двух целочисленных значений и разделен знаком «-». «700» в виде строки было изначально 0700 целым числом.

, например

Dim key As String = slotTimeStart.ToString() & "-" & slotTimeEnd.ToString()

Но как только эти пары значений ключей добавляются в SortedList, они появляются в порядке

 3   "1100-1200"  | List(Of Object)
 4   "1700-1800"  | List(Of Object)
 5   "1900-2000"  | List(Of Object)
 1   "700-800"    | List(Of Object)
 2   "900-1000"   | List(Of Object)

К сожалению, я получаю временные интервалы как два целочисленных значения, которые нельзя изменить.

Есть ли способ принудительной сортировки в SortedList? или это проблема из-за способа хранения моего ключа? Есть ли лучший способ сохранить его?

Ответы [ 4 ]

7 голосов
/ 25 марта 2009

Создайте SortedList(Of String, List(Of Object)), но передайте IComparer(Of String) конструктору , где реализация будет сравнивать ключи в соответствии с требуемым порядком .

Вам придется реализовать это самостоятельно, но это не должно быть слишком сложно - просто разбейте строку на '-', проанализируйте обе стороны с помощью Int32.Parse и отреагируйте соответственно. Возможно, вам даже не придется беспокоиться о детали после «-», если диапазоны клавиш не перекрываются.

РЕДАКТИРОВАТЬ: Вот демо. Он только распечатывает ключи, но этого достаточно, чтобы показать, что они отсортированы так, как вы хотите.

using System;
using System.Collections.Generic;

public class Test
{
    static void Main(string[] args)
    {
        var list = new SortedList<string, int>(new RangeComparer());
        list.Add("900-1000", 10);
        list.Add("1100-1200", 20);
        list.Add("700-800", 30);
        list.Add("1700-18000", 40);
        list.Add("1900-2000", 50);

        foreach (var entry in list)
        {
            Console.WriteLine(entry.Key);
        }
    }
}

public class RangeComparer : IComparer<string>
{
    private static int ParseStartOfRange(string range)
    {
        int hyphenIndex = range.IndexOf('-');
        // Normally do some error checking in case hyphenIndex==-1
        string firstPart = range.Substring(0, hyphenIndex);
        return int.Parse(firstPart);
    }

    public int Compare(string first, string second)
    {
        // In real code you would probably add nullity checks
        int firstStart = ParseStartOfRange(first);
        int secondStart = ParseStartOfRange(second);
        return firstStart.CompareTo(secondStart);
    }
}
1 голос
/ 22 июня 2009

Времена, длина которых меньше 4 цифр, должны начинаться с нуля ('0'), чтобы они имели ту же длину, что и цифры с 4 цифрами. Таким образом, стандартный компаратор будет сравнивать символ 1 строки 1, который теперь будет 0, с символом 1 строки 2, который будет 1, и строка 1 выйдет первой.

1 голос
/ 25 марта 2009

Похоже, вы сортируете это по алфавиту, а не по цифрам. Вам нужно было бы сделать ваш ключ числовым, чтобы получить искомый порядок сортировки.

0 голосов
/ 25 марта 2009

ключи могут быть десятичными и выглядеть как

7.08
9.1
11.12
17.18
19.20

, преобразуйте и отформатируйте в строку при необходимости.

    Dim sl As New SortedList(Of Decimal, Object)
    'sample data
    For x As Integer = 7 To 20 Step 2
        sl.Add(CDec(x + ((x + 1) / 100)), New Object)
    Next

    Dim aKey As Decimal
    Dim slotStart As DateTime = #1:00:00 PM#
    Dim slotEnd As DateTime = #2:00:00 PM#

    aKey = CDec(slotStart.Hour + (slotEnd.Hour / 100))
    sl.Item(aKey) = New Object
...