Способ каскадирования возможен здесь? - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть три строки кода, как показано ниже

local = headers.zip(*data_rows).transpose
local = local[1..-1].map {|dataRow| local[0].zip(dataRow).to_h}
p local

Теперь, если вы посмотрите вышеупомянутые три строки, я должен сохранить результат первой строки в переменной с именем local, так как она будет использоваться в двух местах во второй строке, как я показал, поэтому я не могу каскадировать вторая строка с первой? Я пытался использовать тап, как это

local = headers.zip(*data_rows).transpose.tap{|h|h[1..-1].map {|dataRow| h[0].zip(dataRow).to_h}}

tap возвращает self, как объяснено в документе, так что я не могу получить окончательный результат, когда использую tab? Во всяком случае, другой способ достичь этого результата в одну строку, чтобы мне не пришлось использовать локальную переменную?

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Часто полезно выполнить рабочий код с данными, чтобы лучше понять, что нужно вычислять. Видение transpose и zip, которые часто взаимозаменяемы и используются вместе, было подсказкой, что упрощение может быть возможным (a = [1,2,3]; b = [4,5,6]; a.zip(b) => [[1, 4], [2, 5], [3, 6]] <= [a,b].transpose).

Вот мои данные:

headers=[1,2,3]
data_rows=[[11,12,13],[21,22,23],[31,32,33],[41,42,43]]

и вот что возвращает рабочий код:

local = headers.zip(*data_rows).transpose
local[1..-1].map {|dataRow| local[0].zip(dataRow).to_h}
  #=> [{1=>11, 2=>12, 3=>13}, {1=>21, 2=>22, 3=>23},
  #    {1=>31, 2=>32, 3=>33}, {1=>41, 2=>42, 3=>43}]

Казалось бы, это можно вычислить проще:

data_rows.map { |row| headers.zip(row).to_h }
  #=> [{1=>11, 2=>12, 3=>13}, {1=>21, 2=>22, 3=>23},
  #    {1=>31, 2=>32, 3=>33}, {1=>41, 2=>42, 3=>43}]
0 голосов
/ 09 сентября 2018

Если вы используете Ruby 2.5.0 или более позднюю версию, вы можете использовать yield_self для этого.

local = headers.zip(*data_rows).transpose.yield_self { |h| h[1..-1].map { |dataRow| h[0].zip(dataRow).to_h } }

yield_self аналогично tap в том, что они оба дают self блоку. Разница в том, что возвращается каждым из двух методов.

Object#tap возвращает себя в блок , а затем возвращает себя . Kernel#yield_self возвращает себя в блок, а затем возвращает результат блока .

Вот ответ на предыдущий вопрос, где я привел пару дополнительных примеров того, как каждый из этих методов может быть полезен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...