-1

I have an array of objects with top and left attributes like this:

[{top: 30, left: 20}, {top:50, left:10}, {..}]

I am trying to find how many objects have the approximate same top value. In this case:

[{top: 10, left: 20}, {top:10, left:10}, {top: 10, left: 123},
{top:500, left:10}, {top:2, left: 50}, {top:2, left:400}]

the method would return 5 because there are three objects that have 10 as top value and two objects that have 2 as top value. If there is an object that doesn't share its top value with anything else, it is not taken into account. I am not looking for exact values, but with a flexibility of a 10% of difference on the values so that {top:10, left:20} and {top:10.13, left:20} would be considered as having the same top. So far, I have this:

myarr.group_by { |x| x[:top] }.map { |k,v| [k, v.length] }.to_h

but this would not take into account this margin error. I am not sure how I would change it in order to do so.

sawa
  • 165,429
  • 45
  • 277
  • 381
StarTrek18
  • 323
  • 4
  • 15
  • 1
    Let's say your margin is `2` (absolute), what are you going to do with `[10, 11, 12, 13, 14]`? `12+/-2`? `10+/-2` and `14+/-2`? `10` and `13+/-2`? – Victor Moroz Mar 24 '14 at 23:57
  • How does `10.13` fit within 10% difference of `10`? – sawa Mar 25 '14 at 00:21

1 Answers1

0

Depending on how you want to express "similar", you could do something like this:

def count_similar(a, lower_bound, upper_bound)
  a.count { |h| h[:top] >= lower_bound && h[:top] <= upper_bound }
end

a = [{top: 10, left: 20}, {top:10, left:10}, {top: 10, left: 123},
     {top:500, left:10} , {top:2, left: 50}, {top:2, left:400}]

count_similar(a, 1, 19) #=> 5
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • I was thinking in similarity in terms of how similar is one from the other one. So, is one is just 10% bigger or smaller than the other one, that could be considered the same value. I can't rely on static bounds, because the top values can range from 10000 to 50. I don't have control on that. – StarTrek18 Mar 25 '14 at 00:09
  • I wasn't advocating "static bounds". Since you didn't provide a definition of "similar" I just gave this as a possible basic structure for counting elements for which the value for `:top` falls within a range. You might do some other calculations to compute what you want the upper and lower bounds to be. For example you could make the upper bound 10% higher than the mean or median or whatever, possibly after throwing out some values that you regard as "outliers", based on some criterion. That's entirely up to you. – Cary Swoveland Mar 25 '14 at 01:59