如何按值对字典条目列表进行排序(自定义排序)
How can I sort (Custom Sort) list of Dictionary entry by value
我的哈希表包含 (key, Values[])
例如:
myHashtable[keys, Values[]]
myHashtable.Add[1, Value1];
myHashtable.Add[2, Value2];
myHashtable.Add[3, Value3];
myHashtable.Add[4, Value4];
myHashtable.Add[5, Value5];
其中值1; value2、value3、value4、value5如下。
Value1[name = "Smith"]
Value1[Title= "Mr"]
Value1[Salary = 1000]
Value1[Identity = "S"]
Value2[name = "Peter"]
Value2[Title= "Mr"]
Value2[Salary = 1000]
Value2[Identity = "A"]
Value3[name = "Tom"]
Value3[Title= "Mr"]
Value3[Salary = 1000]
Value3[Identity = "C"]
Value4[name = "Marry"]
Value4[Title= "Ms"]
Value4[Salary = 1000]
Value4[Identity = ""]
Value5[name = "Sam"]
Value5[Title= "Mr"]
Value5[Salary = 1000]
Value5[Identity = "C"]
我想订购此 dictionaryEntry 列表值,其中 Identity 具有 "C" 值,然后是 "A",然后是 "S",然后是“”
排序后的结果应该是这样的。
myHashtable.Add[3, Value3]; // Value3.Identity = "C"
myHashtable.Add[5, Value5]; // Value5.Identity = "C"
myHashtable.Add[2, Value2]; // Value2.Identity = "A"
myHashtable.Add[1, Value1]; // Value1.Identity = "S"
myHashtable.Add[4, Value4]; // Value4.Identity = ""
这是我的尝试。
var result1 = new List<DictionaryEntry>(hashtable.Count);
var result2 = new List<DictionaryEntry>(hashtable.Count);
var result3 = new List<DictionaryEntry>(hashtable.Count);
var result4 = new List<DictionaryEntry>(hashtable.Count);
var result = new List<DictionaryEntry>(hashtable.Count);
foreach (DictionaryEntry entry in hashtable)
{
result.Add(entry);
}
foreach (DictionaryEntry dictionaryEntry in result)
{
var t2 = dictionaryEntry.Value;
switch (t2.Identity)
{
case "C":
result1.Add(dictionaryEntry);
break;
case "A":
result2.Add(dictionaryEntry);
break;
case "S":
result3.Add(dictionaryEntry);
break;
case "":
result4.Add(dictionaryEntry);
break;
default:
break;
}
}
result1.ToList();
result2.ToList();
result3.ToList();
var combinedResult = result1.Union(result2)
.Union(result3)
.Union(result4)
.ToDictionary(k => k.Key, v => v.Value).OrderByDescending(v => v.Value);
如何对 combinedResult 进行排序以提供上面自定义排序的字典条目列表?
非常感谢任何帮助。
谢谢
当使用哈希表实现字典数据结构时,为了实现分摊的 O(1) insert/delete/update 操作,数据未排序。另一方面,当 Dictionary 用平衡树实现时,操作 O(logn) 有点慢,但它们可以按排序方式(通过键)枚举。比如C#字典实现是未排序的,而C++映射是排序的(基于红黑树)
鉴于上述情况(您无法在字典中按需要对数据进行排序),您可以做的是将字典保存为 List/Array,然后按您想要的比较器排序。
这是一个字典和自定义比较器的示例,您可以在其中获取按自定义比较器中的逻辑排序的字典中的值:
public class Data
{
public string Name { get; set; }
public string Identity { get; set; }
}
public class CustomerComparer : IComparer<KeyValuePair<int, Data>>
{
private List<string> orderedLetters = new List<string>() { "C", "A", "S" };
public int Compare(KeyValuePair<int, Data> str1, KeyValuePair<int, Data> str2)
{
return orderedLetters.IndexOf(str1.Value.Identity) - orderedLetters.IndexOf(str2.Value.Identity);
}
}
class Program
{
static void Main(string[] args)
{
Data value1 = new Data { Name = "Name1", Identity = "S" };
Data value2 = new Data { Name = "Name2", Identity = "A" };
Data value3 = new Data { Name = "Name3", Identity = "C" };
Data value4 = new Data { Name = "Name4", Identity = "C" };
Dictionary<int, Data> unsortedDictionary = new Dictionary<int, Data>();
unsortedDictionary.Add(1, value1);
unsortedDictionary.Add(2, value2);
unsortedDictionary.Add(3, value3);
unsortedDictionary.Add(4, value4);
var customSortedValues = unsortedDictionary.Values.OrderBy(item => item, new CustomerComparer()).ToArray();
for (int i=0; i < customSortedValues.Length; i++)
{
var kvp = customSortedValues[i];
Console.WriteLine("{0}: {1}=(Name={2}, Identity={3})", i, kvp.Key, kvp.Value.Name, kvp.Value.Identity);
}
}
}
//Output is:
//0: Name3=C
//1: Name4=C
//2: Name2=A
//3: Name1=S
您还可以使用 SortedDictionary(如@Clockwork-Muse 建议的那样)并传递与上例中类似的 CustomComparer。这实际上取决于您的要求。如果您需要操作保持快速并且只需要为报告排序的值,那么只需在需要这些值时进行排序(如我的示例所示)。如果您将大量访问排序后的值,那么首先让它们排序可能是有意义的。
我的哈希表包含 (key, Values[])
例如:
myHashtable[keys, Values[]]
myHashtable.Add[1, Value1];
myHashtable.Add[2, Value2];
myHashtable.Add[3, Value3];
myHashtable.Add[4, Value4];
myHashtable.Add[5, Value5];
其中值1; value2、value3、value4、value5如下。
Value1[name = "Smith"]
Value1[Title= "Mr"]
Value1[Salary = 1000]
Value1[Identity = "S"]
Value2[name = "Peter"]
Value2[Title= "Mr"]
Value2[Salary = 1000]
Value2[Identity = "A"]
Value3[name = "Tom"]
Value3[Title= "Mr"]
Value3[Salary = 1000]
Value3[Identity = "C"]
Value4[name = "Marry"]
Value4[Title= "Ms"]
Value4[Salary = 1000]
Value4[Identity = ""]
Value5[name = "Sam"]
Value5[Title= "Mr"]
Value5[Salary = 1000]
Value5[Identity = "C"]
我想订购此 dictionaryEntry 列表值,其中 Identity 具有 "C" 值,然后是 "A",然后是 "S",然后是“”
排序后的结果应该是这样的。
myHashtable.Add[3, Value3]; // Value3.Identity = "C"
myHashtable.Add[5, Value5]; // Value5.Identity = "C"
myHashtable.Add[2, Value2]; // Value2.Identity = "A"
myHashtable.Add[1, Value1]; // Value1.Identity = "S"
myHashtable.Add[4, Value4]; // Value4.Identity = ""
这是我的尝试。
var result1 = new List<DictionaryEntry>(hashtable.Count);
var result2 = new List<DictionaryEntry>(hashtable.Count);
var result3 = new List<DictionaryEntry>(hashtable.Count);
var result4 = new List<DictionaryEntry>(hashtable.Count);
var result = new List<DictionaryEntry>(hashtable.Count);
foreach (DictionaryEntry entry in hashtable)
{
result.Add(entry);
}
foreach (DictionaryEntry dictionaryEntry in result)
{
var t2 = dictionaryEntry.Value;
switch (t2.Identity)
{
case "C":
result1.Add(dictionaryEntry);
break;
case "A":
result2.Add(dictionaryEntry);
break;
case "S":
result3.Add(dictionaryEntry);
break;
case "":
result4.Add(dictionaryEntry);
break;
default:
break;
}
}
result1.ToList();
result2.ToList();
result3.ToList();
var combinedResult = result1.Union(result2)
.Union(result3)
.Union(result4)
.ToDictionary(k => k.Key, v => v.Value).OrderByDescending(v => v.Value);
如何对 combinedResult 进行排序以提供上面自定义排序的字典条目列表?
非常感谢任何帮助。 谢谢
当使用哈希表实现字典数据结构时,为了实现分摊的 O(1) insert/delete/update 操作,数据未排序。另一方面,当 Dictionary 用平衡树实现时,操作 O(logn) 有点慢,但它们可以按排序方式(通过键)枚举。比如C#字典实现是未排序的,而C++映射是排序的(基于红黑树)
鉴于上述情况(您无法在字典中按需要对数据进行排序),您可以做的是将字典保存为 List/Array,然后按您想要的比较器排序。
这是一个字典和自定义比较器的示例,您可以在其中获取按自定义比较器中的逻辑排序的字典中的值:
public class Data
{
public string Name { get; set; }
public string Identity { get; set; }
}
public class CustomerComparer : IComparer<KeyValuePair<int, Data>>
{
private List<string> orderedLetters = new List<string>() { "C", "A", "S" };
public int Compare(KeyValuePair<int, Data> str1, KeyValuePair<int, Data> str2)
{
return orderedLetters.IndexOf(str1.Value.Identity) - orderedLetters.IndexOf(str2.Value.Identity);
}
}
class Program
{
static void Main(string[] args)
{
Data value1 = new Data { Name = "Name1", Identity = "S" };
Data value2 = new Data { Name = "Name2", Identity = "A" };
Data value3 = new Data { Name = "Name3", Identity = "C" };
Data value4 = new Data { Name = "Name4", Identity = "C" };
Dictionary<int, Data> unsortedDictionary = new Dictionary<int, Data>();
unsortedDictionary.Add(1, value1);
unsortedDictionary.Add(2, value2);
unsortedDictionary.Add(3, value3);
unsortedDictionary.Add(4, value4);
var customSortedValues = unsortedDictionary.Values.OrderBy(item => item, new CustomerComparer()).ToArray();
for (int i=0; i < customSortedValues.Length; i++)
{
var kvp = customSortedValues[i];
Console.WriteLine("{0}: {1}=(Name={2}, Identity={3})", i, kvp.Key, kvp.Value.Name, kvp.Value.Identity);
}
}
}
//Output is:
//0: Name3=C
//1: Name4=C
//2: Name2=A
//3: Name1=S
您还可以使用 SortedDictionary(如@Clockwork-Muse 建议的那样)并传递与上例中类似的 CustomComparer。这实际上取决于您的要求。如果您需要操作保持快速并且只需要为报告排序的值,那么只需在需要这些值时进行排序(如我的示例所示)。如果您将大量访问排序后的值,那么首先让它们排序可能是有意义的。