C#根据字符串列表对词典排序?
我有以下列表(忽略LST==>部分): 以及字典中的以下键列表(忽略DICT==>部分): 我希望字典按照列表的顺序排序(即用户名在密码之前) 看到了一些这样的样本/有点/不是真的例子。。。但事实并非如此。也希望它尽可能快,而不是野蛮地强迫它C#根据字符串列表对词典排序?,c#,.net,C#,.net,我有以下列表(忽略LST==>部分): 以及字典中的以下键列表(忽略DICT==>部分): 我希望字典按照列表的顺序排序(即用户名在密码之前) 看到了一些这样的样本/有点/不是真的例子。。。但事实并非如此。也希望它尽可能快,而不是野蛮地强迫它 LST可能比DICT有更多的项目。我只关心DICT的排序。DICT在LST中总是有一个匹配的条目。我只需要按第一个顺序进行记录。只需使用OrderBy方法: var SortedDic = dic.OrderBy(o => lst.IndexOf(o
LST可能比DICT有更多的项目。我只关心DICT的排序。DICT在LST中总是有一个匹配的条目。我只需要按第一个顺序进行记录。只需使用
OrderBy
方法:
var SortedDic = dic.OrderBy(o => lst.IndexOf(o.Key));
另一种方法是编写一个小型自定义比较器类,该类使用列表来确定比较值:
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;
}
}
输出
我刚刚看到,您无法控制最初的词典,但愿意创建一个新词典。在这种情况下,您可以简单地使用重载构造函数,该构造函数接受字典和比较器,它将在您的列表中自动排序:
var sortedItems = new SortedDictionary<string, string>(
originalDictionary, new ListComparer(comparisonList));
var sortedItems=新的SortedDictionary(
原始目录,新列表比较器(comparisonList));
使用LINQ这非常简单
首先,设置一个字典
,以表示所需的排序顺序:
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);
然后,您可以从OrderedDictionary
对字典条目进行排序:
var ans = src.Cast<DictionaryEntry>().OrderBy(de => sortOrder[(string)de.Key]);
现在只需使用扩展方法:
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);
这里有三种扩展方法,它们将以不同的方式实现您想要的功能。
它们是这样使用的(keystortItems
和ValueSortItems
是不同的List
列表:
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;
}
DictionaryItems.ListOrderByKey(KeySortItems)
DictionaryItems.ListOrderByValue(ValueSortItems)
DictionaryItems.ListOrderBy(键排序项,(千伏,值)=>千伏键等于(值))
公共静态IEnumerable ListOrderByKey(此IDictionary字典,列表)
{
foreach(列表中的var值)
foreach(字典中的var kv)
如果(千伏键等于(值))
{
屈服回程kv;
打破
}
}
公共静态IEnumerable ListOrderByValue(此IDictionary字典,列表)
{
foreach(列表中的var值)
foreach(字典中的var kv)
如果(千伏值等于(值))
屈服回程kv;
}
公共静态IEnumerable ListOrderBy(此IDictionary字典、列表、Func)
{
foreach(列表中的var值)
foreach(字典中的var kv)
if(函数调用(kv,值))
屈服回程kv;
}
复制和粘贴控制台应用程序。
使用系统;
使用System.Collections.Generic;
公共课程
{
公共静态列表keystortItems{get;set;}=new List()
{
“用户名”,
“密码”,
“项目不在字典中”,
“SampleRequestValue”,
“SampleComplexRequest”
};
公共静态列表值sortitems{get;set;}=new List()
{
“马修”,
"1234",
“项目不在字典中”,
“样本请求”,
“复杂的东西”
};
公共静态字典DictionaryItems{get;set;}=newdictionary()
{
[“密码”]=“1234”,
[“用户名”]=“马修”,
[“SampleComplexRequest”]=“复杂的东西”,
[“SampleRequestValue”]=“样本请求”
};
公共静态void Main()
{
Console.WriteLine(“原始词典”);
foreach(以千伏为单位的var)
{
Console.WriteLine($“{kv.Key}:{kv.Value}”);
}
Console.WriteLine(“\n按键选择”);
foreach(字典中的var kv项。ListOrderByKey(键排序项))
{
Console.WriteLine($“{kv.Key}:{kv.Value}”);
}
Console.WriteLine(“\n按值筛选”);
foreach(字典项中的var kv.ListOrderByValue(ValueSortItems))
{
Console.WriteLine($“{kv.Key}:{kv.Value}”);
}
Console.WriteLine(\通过func键进行筛选”);
foreach(DictionaryItems.ListOrderBy中的var kv(KeySortItems,(kv,value)=>kv.Key.Equals(value)))
{
Console.WriteLine($“{kv.Key}:{kv.Value}”);
}
Console.ReadKey();
}
}
公共静态类扩展
{
公共静态IEnumerable ListOrderByKey(此IDictionary字典,列表)
{
foreach(列表中的var值)
foreach(字典中的var kv)
如果(千伏键等于(值))
屈服回程kv;
}
公共静态IEnumerable ListOrderByValue(此IDictionary字典,列表)
{
foreach(列表中的var值)
foreach(字典中的var kv)
如果(千伏值等于(值))
屈服回程kv;
}
公共静态IEnumerable ListOrderBy(此IDictionary字典、列表、Func)
{
foreach(列表中的var值)
foreach(字典中的var kv)
if(函数调用(kv,值))
屈服回程kv;
}
}
//输出
//原始词典
//密码:1234
//用户名:马修
//SampleComplexRequest:复杂的东西
//SampleRequestValue:示例请求
//按键排序
//用户名:马修
//密码:1234
//SampleRequestValue:示例请求
//SampleComplexRequest:复杂的东西
//按值排序
//用户名:马修
//密码:1234
//SampleRequestValue:示例请求
//SampleComplexRequest:复杂的东西
//通过func按键排序
//用户名:马修
//密码:1234
//SampleRequestValue:示例请求
//SampleComplexRequest:复杂的东西
如果你想让我们忽略DICT==>和LST==>,那么为什么要将它们包含在你的问题中?你应该尽可能让你的问题变得清晰,并删除我们不需要看到的无关内容。对字典排序意味着什么?你是在输出中寻找键/值对列表吗?只是值?(不再是dic)
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);
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