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

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

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

person tadman    schedule 18.11.2009
comment
Код, который я опубликовал, — это просто то, что я записал, не особо вникая в него, я просто хотел придать ему приблизительный вид большей части кода, который я пишу (/me по очереди выбирает -> собирать). Я посмотрю на инъекцию и поможет ли она мне упростить вещи. - person Kostas; 19.11.2009