Сгъване на код при последователно събиране/избиране/отхвърляне/всеки

Играя си с масиви и хешове доста в ruby ​​и в крайна сметка получавам някакъв код, който изглежда така:

sum = two_dimensional_array.select{|i|
  i.collect{|j|
    j.to_i
  }.sum > 5
}.collect{|i|
  i.collect{|j|
    j ** 2
  }.average
}.sum

(Нека всички се преструваме, че примерният код по-горе има смисъл сега...)

Проблемът е, че въпреки че TextMate (избраният от мен редактор) улавя прости {...} или do...end блокове доста лесно, той не може да разбере (което е разбираемо, тъй като дори аз не мога да намеря "правилен" начин да сгъна горното) където започват и завършват горните блокове, за да ги сгънете.

Как бихте сгънали горния примерен код?

PS: като се има предвид, че може да има 2 нива на сгъване, интересуват ме само външните последователни (блоковете с i)


person Kostas    schedule 18.11.2009    source източник


Отговори (1)


Ако трябва да бъда честен, нещо, което е заплетено, вероятно обърква TextMate толкова, колкото всеки друг, който трябва да го поддържа, а това включва и вас в бъдеще.

Всеки път, когато видите нещо, което се събира в една стойност, това е добър случай за използване на Enumerable#inject.

sum = two_dimensional_array.inject(0) do |sum, row|
  # Convert row to Fixnum equivalent
  row_i = row.collect { |i| i.to_i }

  if (row_i.sum > 5)
    sum += row_i.collect { |i| i ** 2 }.average
  end

  sum # Carry through to next inject call
end

Странното във вашия пример е, че използвате select, за да върнете пълния масив, уж преобразуван с помощта на to_i, но всъщност Enumerable#select не прави такова нещо и вместо това отхвърля всички, за които функцията връща нула. Предполагам, че това не е от вашите ценности.

Освен това в зависимост от това как е внедрен вашият метод .average, може да искате да заредите извикването за инжектиране с 0.0 вместо 0, за да използвате стойност с плаваща запетая.

person tadman    schedule 18.11.2009
comment
Кодът, който публикувах, е просто нещо, което записах, без наистина да го разглеждам, просто исках да му дам приблизителния вид на голяма част от кода, който пиша (/me turns select -› collect). Ще разгледам inject и дали ми помага да опростя нещата. - person Kostas; 19.11.2009