Свертывание кода на последовательный сбор / выбор / отклонение / каждый - PullRequest
1 голос
/ 18 ноября 2009

Я много играю с массивами и хешами в 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)

1 Ответ

1 голос
/ 18 ноября 2009

Честно говоря, что-то запутанное, вероятно, сбивает с толку 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 ничего такого не делает, а вместо этого отклоняет любой, для которого функция возвращает nil. Я предполагаю, что это не ваша ценность.

Кроме того, в зависимости от того, как реализован ваш метод .average, вы можете задать начальный вызов инъекции с 0.0 вместо 0, чтобы использовать значение с плавающей запятой.

...