【问题标题】:How sort Dictionary by 2 criterias and subcriteria in c#如何在c#中按2个标准和子标准对字典进行排序
【发布时间】:2021-09-21 13:43:35
【问题描述】:

我想先按 Key 再按 Value 对 myDictionary 进行排序。

Dictionary<int, double> myDictionary = new Dictionary<int, double>()
{
    {1,514},
    {2,509},
    {3,510},
    {4,509},
    {5,517},
    {6,512},
    {7,514},
    {8,511}
}

我需要找到最小值和最大值Value,然后按Key 对其进行排序。

var orderedDict = myObjectDictionary
       .OrderByDescending(a => a.Value)
       .ThenBy(b => b.Key);

但我需要从最大Value 的对象中找到最小Value 最远的对象(使用Key)。如果有两个最小/最大Value 的对象(使用Key)距离对面对象(最小/最大)最远。

之后我需要寻找接近最小值/最大值的对象,以及它们的值是否接近最小值/最大值并且它们离它们最远。

在这种情况下: 最大值 = 5, 517 最小值 = 3, 510

【问题讨论】:

  • 你有什么问题?
  • 其他获取最大值的方法stackoverflow.com/questions/10290838/…
  • @PeterCsala 我的问题是我怎样才能获得这个结果(在这种情况下:Max= 5, 517 Min= 3, 510)?有人可以提供代码示例或其他内容吗?
  • 我可以看到517是最大值,这就是为什么5,517是最大值。但是键 2 和键 4 有两个 509 值。那么为什么是 3,510 是你的最小值?
  • 因为如果它们相邻,我无法获得最小值和最大值。

标签: c# linq dictionary


【解决方案1】:

要求:如果彼此相邻,则无法获得 minma​​x

  • 在以下解决方案中,我假设 myDictionary 键值递增 1。

您可以使用以下代码获得所需的输出:

var groupedByValues = myDictionary.ToLookup(p => p.Value, p => p.Key);

var orderByValues = from item in groupedByValues
                    orderby item.Key ascending
                    select (Value:item.Key, Indexes: item.ToList());
var orderedByValues = orderByValues.ToList();

var maxCandidates = orderByValues.Last();
(int Key, double Value) max = (maxCandidates.Indexes.First(), maxCandidates.Value);
(int Key, double Value)? min = null;

foreach(var item in orderedByValues)
{
    if (item.Indexes.Any(idx => Math.Abs(idx - max.Key) == 1))
        continue;
    else
    {
        min = (item.Indexes.First(), item.Value);
        break;
    }
};

var groupedByValues = myDictionary.ToLookup(p => p.Value, p => p.Key);
  • 这里我们根据值创建组,groupedByValues 如下所示:
514: 1,7
509: 2,4
510: 3
517: 5
512: 6
511: 8

var orderByValues = from item in groupedByValues
                    orderby item.Key ascending
                    select (Value:item.Key, Indexes: item.ToList());

var orderedByValues = orderByValues.ToList();
  • 这里我们只是通过键对上一个集合进行排序
  • orderByValues 只是一个查询,orderedByValues 是它的物化形式:
509: 2,4
510: 3
511: 8
512: 6
514: 1,7
517: 5

var maxCandidates = orderByValues.Last();
(int Key, double Value) max = (maxCandidates.Indexes.First(), maxCandidates.Value);
(int Key, double Value)? min = null;
  • 通过发出orderByValues.Last 命令,我们得到最高值
    • 最高值可以出现多次,这就是为什么我们有Indexes
    • 我从Indexes 中选择了第一个索引,但您可能需要根据您的要求更改此逻辑
  • 我们将maxCandidates 转换为预期的输出格式
  • 我们创建一个min 变量,它可以为空以便能够对其进行初始化

foreach(var item in orderedByValues)
{
    if (item.Indexes.Any(idx => Math.Abs(idx - max.Key) == 1))
        continue;
    else
    {
        min = (item.Indexes.First(), item.Value);
        break;
    }
};
  • 这里我们遍历orderedByValues 集合,以找到满足所有要求的第一个min
  • 我们正在检查最大键和最小候选索引之间的距离
    • 如果有任何索引在最大键旁边,那么我们继续搜索
    • 如果没有一个索引在最大键旁边,那么我们找到了最小值

【讨论】:

    猜你喜欢
    • 2020-10-11
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    相关资源
    最近更新 更多