我有以下列表(忽略LST ==>部分):
LST ==>Username
LST ==>Password
LST ==>SampleRequestValue
LST ==>SampleComplexRequest
LST ==>SampleComplexRequest.SampleTestBValue
LST ==>SampleComplexRequest.SampleTestAValue
和字典中的以下密钥列表(忽略DICT ==>部分):
DICT ==>Password
DICT ==>Username
DICT ==>SampleRequestValue
DICT ==>SampleComplexRequest.SampleTestAValue
DICT ==>SampleComplexRequest.SampleTestBValue
我希望字典按列表的顺序排序(即,密码前的用户名)。
在sorta / kinda /的SO上看到了一些示例,这并不是真正的示例...但实际上不是类似的情况。还希望它尽可能快,而不要强行使用它。
LST可能比DICT包含更多项目。我只关心排序DICT。 DICT在LST中将始终具有匹配的条目。我只想按LST顺序订购DICT。
答案 0 :(得分:1)
另一种方法是编写一个小的自定义比较器类,该类使用列表来确定比较值:
public class ListComparer : IComparer<string>
{
public List<string> ComparisonList { get; set; }
public ListComparer(List<string> comparisonList)
{
ComparisonList = comparisonList;
}
public int Compare(string x, string y)
{
if (ComparisonList == null || !ComparisonList.Contains(x))
return 1;
if (ComparisonList.Contains(y))
return ComparisonList.IndexOf(x).CompareTo(ComparisonList.IndexOf(y));
return -1;
}
}
然后,您可以将其传递给SortedDictionary的构造函数,然后在每次将项添加到字典时都将使用它。这样,您不必每次添加新值时都在字典上调用OrderBy
(这也会带来每次创建一个新字典的负面影响)。
以下代码示例可能会有所帮助。请注意,我们先添加“密码”,然后添加“用户名”,但是当我们输出项目时,它们按预期顺序排列:
static void Main()
{
var comparisonList = new List<string>
{
"Username",
"Password",
"SampleRequestValue",
"SampleComplexRequest",
"SampleComplexRequest.SampleTestBValue",
"SampleComplexRequest.SampleTestAValue",
};
// Add items in an "unorderd" order
var items = new SortedDictionary<string, string>(new ListComparer(comparisonList))
{
{"Password", "LetMeIn"},
{"Username", "JohnDoe"}
};
foreach (var item in items)
{
Console.WriteLine($"{item.Key} = {item.Value}");
}
GetKeyFromUser("\nDone! Press any key to exit...");
}
输出
我刚刚看到您无法控制初始词典,但愿意创建一个新词典。在这种情况下,您只需使用带有字典和比较器的重载构造函数,它将自动在列表中排序:
var sortedItems = new SortedDictionary<string, string>(
originalDictionary, new ListComparer(comparisonList));
答案 1 :(得分:1)
使用LINQ非常简单。
首先,设置一个Dictionary<string,int>
来代表所需的排序顺序:
var orderList = new[] { "Username", "Password", "SampleRequestValue", "SampleComplexRequest", "SampleComplexRequest.SampleTestBValue", "SampleComplexRequest.SampleTestAValue" }
.ToList();
var sortOrder = orderList
.Select((s, p) => new { s, p })
.ToDictionary(sp => sp.s, sp => sp.p);
然后您可以将DictionaryEntry
中的OrderedDictionary
排序:
var ans = src.Cast<DictionaryEntry>().OrderBy(de => sortOrder[(string)de.Key]);
如果您希望答案是OrderedDictionary
,则可以使用扩展方法转换回去:
public static class IEnumerableExt {
public static OrderedDictionary ToOrderedDictionary<TKey,TValue,TObj>(this IEnumerable<TObj> src, Func<TObj,TKey> keyFn, Func<TObj, TValue> valueFn) {
var ans = new OrderedDictionary();
foreach (var s in src)
ans.Add(keyFn(s), valueFn(s));
return ans;
}
}
现在只需使用扩展方法:
var odans = ans.ToOrderedDictionary(s => s.Key, s => s.Value);
答案 2 :(得分:0)
只需使用OrderBy
方法:
var SortedDic = dic.OrderBy(o => lst.IndexOf(o.Key));
答案 3 :(得分:0)
它们的用法如下(KeySortItems
和ValueSortItems
是不同的List<string>
列表:
DictionaryItems.ListOrderByKey(KeySortItems)
DictionaryItems.ListOrderByValue(ValueSortItems)
DictionaryItems.ListOrderBy(KeySortItems, (kv, value) => kv.Key.Equals(value))
public static IEnumerable<KeyValuePair<TKey, TValue>> ListOrderByKey<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, List<TValue> list)
{
foreach (var value in list)
foreach (var kv in dictionary)
if (kv.Key.Equals(value))
{
yield return kv;
break;
}
}
public static IEnumerable<KeyValuePair<TKey, TValue>> ListOrderByValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, List<TValue> list)
{
foreach (var value in list)
foreach (var kv in dictionary)
if (kv.Value.Equals(value))
yield return kv;
}
public static IEnumerable<KeyValuePair<TKey, TValue>> ListOrderBy<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, List<TValue> list, Func<KeyValuePair<TKey, TValue>, TValue, bool> func)
{
foreach (var value in list)
foreach (var kv in dictionary)
if (func.Invoke(kv, value))
yield return kv;
}
using System;
using System.Collections.Generic;
public class Program
{
public static List<string> KeySortItems { get; set; } = new List<string>()
{
"Username",
"Password",
"Item not in Dictionary",
"SampleRequestValue",
"SampleComplexRequest"
};
public static List<string> ValueSortItems { get; set; } = new List<string>()
{
"Mathew",
"1234",
"Item not in Dictionary",
"Sample Request",
"Something Complex"
};
public static Dictionary<string, string> DictionaryItems { get; set; } = new Dictionary<string, string>()
{
["Password"] = "1234",
["Username"] = "Mathew",
["SampleComplexRequest"] = "Something Complex",
["SampleRequestValue"] = "Sample Request"
};
public static void Main()
{
Console.WriteLine("Original Dictionary");
foreach (var kv in DictionaryItems)
{
Console.WriteLine($"{kv.Key} : { kv.Value}");
}
Console.WriteLine("\nSorted by Key");
foreach (var kv in DictionaryItems.ListOrderByKey(KeySortItems))
{
Console.WriteLine($"{kv.Key} : { kv.Value}");
}
Console.WriteLine("\nSorted by Value");
foreach (var kv in DictionaryItems.ListOrderByValue(ValueSortItems))
{
Console.WriteLine($"{kv.Key} : { kv.Value}");
}
Console.WriteLine("\nSorted by Keys via func");
foreach (var kv in DictionaryItems.ListOrderBy(KeySortItems, (kv, value) => kv.Key.Equals(value)))
{
Console.WriteLine($"{kv.Key} : { kv.Value}");
}
Console.ReadKey();
}
}
public static class Extensions
{
public static IEnumerable<KeyValuePair<TKey, TValue>> ListOrderByKey<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, List<TValue> list)
{
foreach (var value in list)
foreach (var kv in dictionary)
if (kv.Key.Equals(value))
yield return kv;
}
public static IEnumerable<KeyValuePair<TKey, TValue>> ListOrderByValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, List<TValue> list)
{
foreach (var value in list)
foreach (var kv in dictionary)
if (kv.Value.Equals(value))
yield return kv;
}
public static IEnumerable<KeyValuePair<TKey, TValue>> ListOrderBy<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, List<TValue> list, Func<KeyValuePair<TKey, TValue>, TValue, bool> func)
{
foreach (var value in list)
foreach (var kv in dictionary)
if (func.Invoke(kv, value))
yield return kv;
}
}
//OUTPUT
//Original Dictionary
//Password : 1234
//Username : Mathew
//SampleComplexRequest : Something Complex
//SampleRequestValue : Sample Request
//Sorted by Key
//Username : Mathew
//Password : 1234
//SampleRequestValue : Sample Request
//SampleComplexRequest : Something Complex
//Sorted by Value
//Username : Mathew
//Password : 1234
//SampleRequestValue : Sample Request
//SampleComplexRequest : Something Complex
//Sorted by Keys via func
//Username : Mathew
//Password : 1234
//SampleRequestValue : Sample Request
//SampleComplexRequest : Something Complex