linq 如何按关键字对字典进行排序

7lrncoxx  于 2022-12-06  发布在  其他
关注(0)|答案(8)|浏览(181)

我有字典Dictionary<string, Point>
关键字是c1,c3,c2,t1,,t4,t2我想将它们排序为c1,c2,c3,t1,t2,t3
我试着用

Input.OrderBy(key => key.Key );

但它不起作用
你知道怎么解决吗

r6vfmomb

r6vfmomb1#

Input.OrderBy不会排序字典,它会建立以特定顺序传回项目的查询。
也许OrderedDictionary给了你你想要的。
或者使用通用SortedDictionary

yebdmbv4

yebdmbv42#

将未排序的对象加载到SortedDictionary对象中,如下所示:

var sortedCustomerData 
    = new SortedDictionary<string, string>(unsortedCustomerData);

其中unsortedCustomerData是相同的泛型类型(Dictionary string, string或在您的情况下为string, point)。
根据msdn:SortedDictionary<TKey, TValue>(IDictionary<TKey, TValue>):初始化SortedDictionary<TKey, TValue>类别的新执行严修,此类别包含从指定的IDictionary<TKey, TValue>复制的元素,并使用索引键型别的预设IComparer<T>实作。

w8f9ii69

w8f9ii693#

由于Input.OrderBy创建了一个以有序顺序返回项的查询,因此只需将其分配给同一个字典即可。
objectDict = objectDict.OrderBy(obj => obj.Key).ToDictionary(obj => obj.Key, obj => obj.Value);

zc0qhyus

zc0qhyus4#

这只是猜测,但看起来像是您假设它要对输入进行排序。OrderBy方法实际上返回包含相同值的IOrderedEnumerable的有序示例。如果您希望保留返回值,可以执行以下操作:

IOrderedEnumerable orderedInput
orderedInput = Input.OrderBy(key=>key.Key)

大多数修改集合的方法都遵循同样的模式。这样做是为了不改变原始集合示例。这可以防止你无意中改变示例。如果你只想使用排序后的示例,那么你只需如上所示将变量设置为方法的返回值。

uqdfh47h

uqdfh47h5#

下面的代码使用另外两个listsort字典。

using System;
using System.Collections.Generic;
using System.Drawing;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            Dictionary<string,Point> r=new Dictionary<string,Point>();
            r.Add("c3",new Point(0,1));
            r.Add("c1",new Point(1,2));
            r.Add("t3",new Point(2,3));
            r.Add("c4",new Point(3,4));
            r.Add("c2",new Point(4,5));
            r.Add("t1",new Point(5,6));
            r.Add("t2",new Point(6,7));
            // Create a list of keys
            List<string> zlk=new List<string>(r.Keys);
            // and then sort it.
            zlk.Sort();
            List<Point> zlv=new List<Point>();
            // Readd with the order.
            foreach(var item in zlk) {
                zlv.Add(r[item]);
            }
            r.Clear();
            for(int i=0;i<zlk.Count;i++) {
                r[zlk[i]]=zlv[i];
            }
            // test output
            foreach(var item in r.Keys) {
                Console.WriteLine(item+" "+r[item].X+" "+r[item].Y);
            }
            Console.ReadKey(true);
        }
    }
}

上面代码的输出如下所示。

c1 1 2
c2 4 5
c3 0 1
c4 3 4
t1 5 6
t2 6 7
t3 2 3
bxjv4tth

bxjv4tth6#

我以前

var l =  Input.OrderBy(key => key.Key);

我把它转换成了字典

nfeuvbwi

nfeuvbwi7#

这取决于你的需要。如果你需要一个列表的键一次排序将工作。我做了下面的测试,你可以运行,看看如何实现键排序。

[Fact]
public void SortDict()
{
    // Arrange
    var initial = new Dictionary<string, bool>()
    {
        {"c1", true },
        {"c3", true },
        {"c2", true },
        {"t1", true },
        {"t3", true },
        {"t2", true },
    };
    var expected = new List<string>() { "c1", "c2", "c3", "t1", "t2", "t3" };

    // Act
    var actual = initial.OrderBy(k => k.Key).Select(k => k.Key)
        .ToList();

    // Assert
    actual.ShouldBeEquivalentTo(expected);
}

如果你需要你的键总是被排序的话,我会使用一个SortedDictionary。在下面我将使用它的构造函数创建一个SortedDictionary,用旧的字典作为参数。你可以运行测试并验证结果。

[Fact]
public void SortDictUsingLinq()
{
    // Arrange
    var initial = new Dictionary<string, bool>()
    {
        {"c1", true },
        {"c3", true },
        {"c2", true },
        {"t1", true },
        {"t3", true },
        {"t2", true },
    };
    var expected = new List<string>() { "c1", "c2", "c3", "t1", "t2", "t3" };

    // Act
    var sortedDict = new SortedDictionary<string, bool>(initial);

    // Assert
    sortedDict.Keys.ToList().ShouldBeEquivalentTo(expected);
}

SortedDictionary的插入和检索时间为 O(log n),而Dictionary的插入和检索时间为 O(1)。因此,如果只有一次或很少需要对元素进行排序,并且经常插入和删除,则需要一次排序。

2w2cym1i

2w2cym1i8#

好的,检查一下这个,应该能用

var r = new Dictionary<string, Point>();
r.Add("c3", new Point(0, 0));
r.Add("c1", new Point(0, 0));
r.Add("t3", new Point(0, 0));
r.Add("c4", new Point(0, 0));
r.Add("c2", new Point(0, 0));
r.Add("t1", new Point(0, 0));
r.Add("t2", new Point(0, 0));
var l = r.OrderBy(key => key.Key);
var dic = l.ToDictionary((keyItem) => keyItem.Key, (valueItem) => valueItem.Value);

foreach (var item in dic)
{

    Console.WriteLine(item.Key);
}
Console.ReadLine();

相关问题