2017-02-01 4 views
1

Я довольно новыми для Ruby, и я пытаюсь понять пример метода отображения, который я наткнулся на:Понимание карты в Ruby,

{:a => "foo", :b => "bar"}.map{|a, b| "#{a}=#{b}"}.join('&') 

, который возвращает:

=> "a=foo&b=bar" 

Я не» t понять, как

b=bar 

возвращается. Строка интерполяции, что сбивает с толку меня, как кажется, было бы вернуть что-то вроде:

=> "a=foo&bbar" 
+0

Почему вы так думаете? – sawa

+0

Hi Sawa. Потому что в строковой интерполяции я не вижу, где 'b' будет равно' bar'. Это похоже на то, что на самом деле это будет 'afoo = & bbar' – mxmxx

ответ

3

Символ ключа :a и локальная переменная a не имеют ничего общего. Имена только совпадают. Вместо этого рассмотрите этот код:

{ 
    var1: "value1", 
    var2: "value2" 
}.map do |key, value| 
    "#{key}=#{value}" 
end.join('&') 
# => "var1=value1&var2=value2" 

Здесь переменные разные. То, что map делает, как each, перебирает каждую ключ-значение пара в хэш. Это означает, что вы можете делать вещи, как это, тоже, чтобы упростить:

{ 
    var1: "value1", 
    var2: "value2" 
}.map do |pair| 
    pair.join('=') 
end.join('&') 
# => "var1=value1&var2=value2" 

Обычно при переборе над Hash вы должны использовать имена, как k,v или key,value быть ясно, что вы работаете на.

Если вы когда-нибудь запутался, что происходит внутри в итерации цикла, вы можете отлаживать, как это:

{ 
    var1: "value1", 
    var2: "value2" 
}.map do |pair| 
    puts pair.inspect 
    pair.join('=') 
end.join('&') 

Это дает вам этот вывод:

[:var1, "value1"] 
[:var2, "value2"] 

Этот метод очень помогает , Есть даже короткое обозначение для этого:

p pair 
+1

Действительно оцените @tadman. Ваш пример очистил все, так как это была локальная переменная, такая же, как символ, который меня путал. – mxmxx

+0

Для меня блоки и символы были самыми запутанными и внешними аспектами Ruby, чтобы понять, когда я впервые его изучил. Применяется к привыканию, но как только вы это сделаете, у вас есть много удивительных вещей, которые вы можете сделать с ними. Рад, что смог помочь. – tadman

7
> {:a => "foo", :b => "bar"}.map{|key, value| "#{key}=#{value}"} 
#=> ["a=foo", "b=bar"] 

map метод будет получать каждый элемент хэша как key и value пару

"#{key}=#{value}" является Строка Интерполяция, который добавляет = между вашими key и value

Используя этот синтаксис, все, что находится между битами открытия # {и закрытия} , оценивается как код Ruby, и результатом этой оценки будет , встроенный в его окружение.

Array#join будет возвращает строку, созданную путем преобразования каждого элемента массива в строку, разделенных данного сепаратора.

так вот в вашем случае:

> ["a=foo", "b=bar"].join('&') 
#=> "a=foo&b=bar" 

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

> {:a => "foo", :b => "bar"}.to_query 
#=> "a=foo&b=bar" 
+0

Похоже, что OP больше путается с аргументами' map', чем с интерполяцией строк. –

+0

@ EricDuminil: да, для этого я объясню, что из хэша он выберет «ключ» и «значение» –

1

Существует 2 вызова методов, встречающихся здесь, карта и соединение. Один из способов сделать его более понятным и понятным - это разделить эти два метода и изменить ключевые слова, используемые в методе карты. Таким образом, вместо

{:a => "foo", :b => "bar"}.map{|a, b| "#{a}=#{b}"}.join('&')

Позволяет иметь

{:a => "foo", :b => "bar"}.map{|key, value| "#{key}=#{value}"}

Это возвращает массив.#=> ["a=foo", "b=bar"]

Сейчас:

["a=foo", "b=bar"].join('&')

производит жалом #=> "a=foo&b=bar"

Карта является итерация двух пар ключ/значение и создание строки с «=» между ними и возвращает его в массив. Он будет перебирать все пары ключ/значение в суровом. Наш пример имеет только 2.

Присоединение присоединяет два элемента массива вместе с символом '&' между ними и возвращает его как строку. Он будет прикреплять все элементы массива независимо от его размера.

Что помогло мне изучить карту и присоединиться, это открыть irb или pry и создать несколько хэшей и массивов и поиграть с ними. Я настоятельно рекомендую использовать уникальные имена для ваших значений, которые объясняют, что происходит. Надеюсь, это поможет вам.