SortedList не сортируется по ключу – VB.NET
-
21-08-2019 - |
Вопрос
Мне нужна пара ключ-значение, которую я хочу отсортировать, поэтому я решил использовать 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?или эта проблема связана с тем, как я храню свой ключ?Есть ли лучший способ его хранения?
Решение
Создать 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);
}
}
Другие советы
Похоже, вы сортируете их по алфавиту, а не по номерам.Вам нужно будет сделать свой ключ числовым, чтобы получить тот порядок сортировки, который вы ищете.
Времена длиной менее 4 цифр должны иметь префикс нуля («0»), чтобы сделать их такой же длины, как и времена с 4 цифрами.Таким образом, стандартный компаратор сравнит символ 1 строки 1, который теперь будет равен 0, с символом 1 строки 2, которая будет равна 1, и строка 1 выйдет первой.
могут ли ключи быть десятичными и выглядеть так
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