【问题标题】:Comparing difference between values in dictionary比较字典中值之间的差异
【发布时间】:2015-08-14 09:15:12
【问题描述】:

我有一个Dictionary<string, float> 并想从中选择 KeyValuePairs,其中浮点值之间的差异小于某个阈值。

这是字典:

Dictionary<string, float> heights = new Dictionary<string, float> ();

示例条目:

"first", 61.456
"second", 80.567
"third", 62.456
"4", 59.988
"5", 90.34
"6", 82.123

我需要这些元素,它们的值略有不同,例如列表中的“第一”、“第三”和“4”或类似的东西。差异是给定的浮点值,比如 3.5

Linq 可以实现吗?

我尝试使用循环来做到这一点,但不知何故它变得非常混乱......

【问题讨论】:

  • 发布您的代码以获得良好的响应和更好的理解
  • 有什么区别?关键和价值?
  • 不,每个字典元素的值之间的差异。 (Math.Abs​​(heights[key1] - heights[key2]))
  • 呃,最好发布一个示例列表并标记您想要选择的值。
  • 所以第一个值是您的“基础”值,应该选择相差小于或正好 3.5 的所有值?

标签: c# linq dictionary


【解决方案1】:

您可以创建查找接近值并接受两个参数的自定义方法:保存值的字典和用于保存最大查找范围的浮点数:

    static Dictionary<string, float> FindRange(Dictionary<string, float> dict, float precision)
    {
        Dictionary<string, float> temp = new Dictionary<string, float>();
        List<int> counter = new int[dict.Count].ToList(); float[] values = dict.Values.ToArray();            

        for (int i = 0; i < values.Length; i++)                            
            for (int i2 = 0; i2 < values.Length; i2++)
                if (i2 != i && Math.Abs(values[i] - values[i2]) < precision) counter[i]++;            

        for (int i = 0; i < values.Length; i++)    
           if (Math.Abs(values[i] - values[counter.IndexOf(counter.Max())]) < precision) 
               temp.Add(dict.FirstOrDefault(kv => kv.Value == values[i]).Key, values[i]);

        return temp;
    }

使用示例:

static void Main()
{
        Dictionary<string, float> heights = new Dictionary<string, float>()
        {

            {"first", 61.456f},
            {"second", 80.567f},
            {"third", 62.456f},
            {"4", 59.988f},
            {"5", 90.34f},
            {"6", 82.123f}                
        };

        // returns max sequence of elements with difference less than 3f
        var newDict = FindRange(heights, 3f);

        foreach (var item in newDict)
        {
            Console.WriteLine(item.Key + "   "  + item.Value);
        }
}

输出:

first 61,456
third 62,456
4     59,988

【讨论】:

    【解决方案2】:

    您可以先按值对条目进行排序,然后比较附近的条目会更容易。

    var list = heights.ToList();
    list.Sort((a,b) => {return a.Value.CompareTo(b.Value);});
    bool first = true;
    for (int i = 1; i < list.Count; ++i)
    {
        if (Math.Abs(list[i-1].Value - list[i].Value) < threshold)
        {
            if (first)
            {
                first = false;
                Console.WriteLine(list[i-1]);
            }
            Console.WriteLine(list[i]);
        }
    }
    

    dotnetfiddle here 上的一个工作示例。

    【讨论】:

      【解决方案3】:

      类似:

      List<KeyValuePair<string,float>> matching = new List<KeyValuePair<string,float>>();
      
      int i = 0;
      var all = _dict.Select(kvp => kvp).ToList().OrderBy(kvp => kvp.Value);
      all.ForEach(kvp => {
          if(i < all.Count() - 1 && Math.Abs(all[i+1].Value - kvp.Value) < threshhold)
          {
               matching.Add(kvp);
               if(i == all.Count() - 1) matching.add(all[i+1]); // Need to manually add the final entry if it's a match
          }
          i++;
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-16
        • 2023-03-07
        • 1970-01-01
        • 2016-02-04
        • 1970-01-01
        • 2019-08-03
        • 1970-01-01
        • 2010-12-01
        相关资源
        最近更新 更多