使用LINQ从C#通用字典查询值

时间:2015-02-19 19:28:13

标签: c# linq dictionary

这是我的代码:

Dictionary<double, long> dictionary = new Dictionary<double, long>();
dictionary.Add(99, 500);
dictionary.Add(98, 500);
dictionary.Add(101, 8000);
dictionary.Add(103, 6000);
dictionary.Add(104, 5);
dictionary.Add(105, 2000);

double price = 100;

我想要的查询是: 最接近价格和最低值的关键字。 所以在上面的例子中它应该返回99。 我如何在LINQ中编码? 我见过很多linq的例子,但是我无法根据我的需要调整它们b​​ / c我的查询有两个条件。

感谢您的帮助。

编辑: 根据@nintendojunkie和@DmitryMartovoi的评论,我不得不重新考虑我的方法。 如果我优先考虑最接近价格的密钥,那么结果价值可能不是最低的,如果我优先考虑价值,那么密钥可能离价格太远,因此查询必须优先考虑密钥和价值相同并给我最低价值最接近价格的关键。关键和价值都同样重要。 任何人都可以帮忙吗? 谢谢

7 个答案:

答案 0 :(得分:1)

你可以这样做:

var result = dictionary.Select(c => new { c.Key, Diff = Math.Abs(price - c.Key) + Math.Abs(price - c.Value), c.Value }).OrderBy(c => c.Diff).FirstOrDefault();

答案 1 :(得分:1)

别忘了 - 你使用字典。字典只有唯一的键。我认为您将此结构视为List<KeyValuePair<double, long>>。如果是这样 - 请看这个例子:

var minimumKeyDifference = dictionary.Min(y => Math.Abs(y.Key - price));
var minimumItems = dictionary.Where(x => Math.Abs(x.Key - price).Equals(minimumKeyDifference));
var desiredKey = dictionary.First(x => x.Value.Equals(minimumItems.Where(y =>  y.Key.Equals(x.Key)).Min(y => y.Value))).Key;

答案 2 :(得分:1)

您说您需要找到最接近的价格最低价值,但您没有定义将优先级归于两者之间的规则。在下面,我将它们归为相同的优先级:价格距离为1等于值1.

var closest = 
    dictionary.OrderBy(kvp => Math.Abs(kvp.Key - price) + kvp.Value).First();

OrderBy(…).First()应由MinBy(…)运算符替换(如果可用),以提高性能。

修改:如果该值仅用作决胜局,则使用此值(也由Giorgi Nakeuri发布):

var closest = 
    dictionary.OrderBy(kvp => Math.Abs(kvp.Key - price))
              .ThenBy(kvp => kvp.Value)
              .First();

答案 3 :(得分:0)

var price = 100.0;

var nearestKey = (from pair in dictionary
                 let diff = Math.Abs(pair.Key - price)
                 select new {Key = pair.Key, Diff = diff}
                 order by diff desc).First().Key;
var minValue = dictionary[nearestKey];

答案 4 :(得分:0)

也许你想要一个神奇的linq查询,但我建议尝试下面的内容。

public static class MyExtensions
{
    public static double? GetNearestValue (this IDictionary<double, long> dictionary, double value)
    {
        if (dictionary == null || dictionary.Count == 0)
            return null;

        double? nearestDiffValue = null;
        double? nearestValue = null;

        foreach (var item in dictionary) {
            double currentDiff = Math.Abs (item.Key - value);
            if (nearestDiffValue == null || currentDiff < nearestDiffValue.Value) {
                nearestDiffValue = currentDiff;
                nearestValue = item.Value;
            }
        }

        return nearestValue;
    }
}

并像这样打电话

Console.WriteLine (dictionary.GetNearestValue (100d));

答案 5 :(得分:0)

var min = dictionary
            .OrderBy(pair => pair.Value)
            .Select(pair =>
                new
                {
                    k = pair.Key,
                    d = Math.Abs(pair.Key - price)
                })
            .OrderBy(t => t.d)
            .Select(t => t.k)
            .FirstOrDefault();

答案 6 :(得分:0)

如果您将字典密钥的数据类型更改为decimal而不是double,则以下情况有效。

decimal price = 100;
decimal smallestDiff = dictionary.Keys.Min(n => Math.Abs(n - price));
var nearest = dictionary.Where(n => Math.Abs(n.Key - price) == smallestDiff)
                        .OrderBy(n => n.Value).First();

如果您使用double,由于四舍五入问题,这可能会失败,但decimal更适合与钱有关的任何事情来避免这些问题。