比较字典中数值的差异

4

我有一个 Dictionary<string,float>,想要从中选择键值对,其中浮点值之间的差小于某个特定阈值。

这是字典:

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

我需要这些元素,它们的值有一个小差别,例如列表或类似东西中的“first”,“third”和“4”。这个差别是一个给定的浮点值,比如说3.5。
使用Linq可以实现这个吗?
我尝试使用循环来实现这个,但是变得非常混乱...

2
发布您的代码以获得更好的回应和更好的理解。 - sujith karivelil
2
什么之间的区别?键和值? - shay__
不,是每个字典元素之间的值的差异。(Math.Abs(heights[key1] - heights[key2])) - sergio
最好您发布一个样本列表,并标记您想要选择的值。 - Steffen Winkler
所以第一个值是您的“基准”值,所有与其相差不超过3.5的值都应被选中? - Steffen Winkler
你的描述不够具体,你是在寻找一个序列还是所有序列?差异是静态阈值还是相对于标准偏差?在你的例子中,为什么要选择“第一”,“第三”和“4”,而不是“第二”和“6”?目前有许多不同的算法可以回答你的问题。 - Tamir Daniely
3个回答

1
您可以先按值对条目进行排序,然后比较相邻的条目会更容易。
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的工作示例 在这里

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

0

类似这样:

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++;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接