簡體   English   中英

使用LINQ從C#通用詞典查詢值

[英]Query values from a C# Generic Dictionary using LINQ

這是我的代碼:

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示例,但是我無法根據我的需要調整它們中的任何一個,因為我的查詢有2個條件。

謝謝你的幫助。

編輯:基於@nintendojunkie和@DmitryMartovoi的評論,我不得不重新考慮我的方法。 如果我對最接近價格的鍵進行優先級排序,則結果值可能不是最低的;如果我對優先級進行優先排序,則鍵值可能與價格相距太遠,因此查詢將必須對鍵值和優先級都進行優先排序,並給我最低的值價格最接近的關鍵。 關鍵和價值同等重要。 有人可以幫忙嗎? 謝謝

您可以這樣操作:

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();

別忘了-您使用字典。 詞典只有唯一的鍵。 我認為您認為此結構為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;

您說需要找到最接近的價格最低的價格,但是您沒有定義兩個屬性之間的優先級分配規則。 在下面,我將它們的優先級賦予相同:價格距離1等於值1。

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

為了提高性能,應該用MinBy(…)運算符替換OrderBy(…).First()

編輯 :如果該值僅旨在充當決勝局,則使用此值(也由Giorgi Nakeuri發布):

var closest = 
    dictionary.OrderBy(kvp => Math.Abs(kvp.Key - price))
              .ThenBy(kvp => kvp.Value)
              .First();
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];

也許您想要一個神奇的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));
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();

如果將字典鍵的數據類型更改為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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM