2012-07-13 11 views
11

Potrzebuję pomocy z czymś, co wydaje się proste, ale wprowadza mnie w zakłopotanie. Próbujesz napisać jakąś metodę dopasowania rozmytego, która radzi sobie z różnicami w formacie pomiędzy wartością, która jest obliczana w razie potrzeby, a która jest faktycznie dostępna z listy wyboru.jak znaleźć najlepszy pasujący element w tablicy liczb?

Wartość (cena wykonania opcji) jest zawsze wyliczoną wartością Float, taką jak 85.0 lub Int.

tablica zawiera numery w postaci łańcucha, nieprzewidywalne, w każdym przyroście, czy będą one pokazano zaokrąglone pewnym przecinku (w tym dodatkowe zerami jak 5.50) lub bez (jak 85 przecinku), np .:

select_list = ["77.5", "80", "82.5", "85", "87.5", "90", "95", "100", "105"] 

Nie jestem pewien, jak napisać prostą linię lub dwa z kodu, który zwróci najbliższy pasujący element (według wartości liczbowej), jaki pojawia się w tablicy. Na przykład, jeśli select_list.contains? 85.0 zwrócił "85"

W rzeczywistości, wybory wyboru pochodzą z obiektu HTML Watir::Webdriver browser.select_list(:id, "lstStrike0_1"), którego widoczny tekst (nie wartość HTML) są tymi liczbami; może jest bardziej bezpośredni sposób, aby po prostu zadzwonić pod numer browser.select_list(:id, "lstStrike0_1").select X bez konieczności wymyślania w Watir jak przekonwertować wszystkie te wybory do tablicy Ruby?

+0

Inną kwestią http://stackoverflow.com/q/6358860/1069375 świeci mi jak łatwo przekonwertować listę select_ Watir do potrzebnej tablicy: 'selectContent = browser.select_list (: id," lstStrike0_1 "). options.map (&: text)' – Marcos

Odpowiedz

20
xs = ["77.5", "80", "82.5", "85", "87.5", "90", "95", "100", "105"] 
xs.min_by { |x| (x.to_f - 82.4).abs } 
#=> "82.5" 
+0

Najbardziej zwięzły sposób, jaki widzę. Dla moich celów kompletne rozwiązanie połączone w jedną linię to '$ browser.select_list (: id," lstStrike0_0 "). Select (strikelist = $ browser.select_list (: id," lstStrike0_0 "). Options.map (&: text)) .min_by {| x | (x.to_f - sigitem [: strikel]). abs} ' – Marcos

5

nie jestem programista Ruby więc to nie może być najlepszym sposobem na to

def select_closest(list, target)        
    return (list.map {|x| [(x.to_f - target).abs, x]}).min[1] 
end                

select_list = ["77.5", "80", "82.5", "85", "87.5", "90", "95", "100", "105"] 

puts select_closest(select_list, 81) # yields 80 
+0

I esp. podobnie jak w przypadku niedokładnych wartości liczbowych (81 vs najbliższe 80), nawet jeśli nie wspomniałem o tym wyraźnie, ale jest on podatny na wystąpienie. Dzięki! – Marcos

Powiązane problemy