Comparing the difference between the values ​​in the dictionary

I have a Dictionary<string, float> and you want to select KeyValuePairs from where the difference between the float values ​​is less than a certain amount.

This is a dictionary:

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

sample entries:

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

I need these elements with a small difference in their values, for example. β€œfirst”, β€œthird” and β€œ4” in the list or something similar. difference is the set value of the float, say 3.5

Is it possible to achieve this Linq?

I tried to do this with loops, but it really gets messy ...

+4
source share
3 answers

You can create your own method that searches for close values ​​and takes two parameters: a dictionary that contains values ​​and float, which are used to store the maximum search range:

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

Usage example:

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

Exit:

 first 61,456 third 62,456 4 59,988 
+1
source

You can sort the records by value first, and then it will be easier to compare the neighboring records.

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

A working example on dotnetfiddle is here .

+1
source

Sort of:

 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 a match } i++; }); 
0
source

All Articles