Сворачивание кода при последовательном сборе / выборе / отклонении / каждом

StackOverflow https://stackoverflow.com/questions/1757181

  •  20-09-2019
  •  | 
  •  

Вопрос

Я довольно много играю с массивами и хэшами в 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).

Это было полезно?

Решение

Честно говоря, что-то такое запутанное, вероятно, сбивает 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, вы можете захотеть заполнить вызов inject значением 0.0 вместо 0, чтобы использовать значение с плавающей запятой.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top