Как получить доступ к первому элементу в массиве хэш-значений


У меня есть хэш, значение которого представляет собой массив текстов песен (line1, line2 и т. д..)

Код:

class Song
    def initialize(lyrics)
       @lyrics = lyrics 
    end
    def get_song_name()
        puts @lyrics.keys
    end
    def get_first_line()
        puts @lyrics.values[0]
    end
end

wasted = Song.new({"Wasted" => ["I like us better when we're wasted",
    "It makes it easier to see"]})

real_world = Song.new("Real World" => ["Straight up what do you want to learn about here", "if i was someone else would this all fall apart"])

wasted.get_song_name()
wasted.get_first_line()
#=>I like us better when we're wasted
#=>It makes it easuer to see
Поэтому, когда я вызываю wasted.get_first_line, я хочу, чтобы он получил первый элемент в массиве значения. Я попытался сделать @lyrics.values[0], но он возвращает обе строки песни вместо первой.

Как мне это сделать?

3   4   2015-08-16 20:59:47

3 ответа:

Вы должны понимать, что в приведенном выше коде @lyrics есть хэш. Вот что вы делаете и к чему это приводит:

@lyrics
# => {"Wasted"=>["I like us better when we're wasted", "It makes it easier to see"]} 


@lyrics.values
# => [["I like us better when we're wasted", "It makes it easier to see"]] 

@lyrics.values[0]
# => ["I like us better when we're wasted", "It makes it easier to see"] 

@lyrics.values[0][0]

# => "I like us better when we're wasted" 
Таким образом, чтобы получить доступ к первой строке, необходимо получить первый элемент массива значений. то есть
@lyrics.values[0][0]

Или

@lyrics.values.first.first

Давайте использовать этот хэш, например:

x = {foo: [:bar, :baz]}

x.values             # => [[:bar, :baz]]
x.values.first       # => [:bar, :baz]
x.values.first.first # => :bar
Другими словами, @lyrics.values[0] вернет первое значение в хэше @lyrics, который является массивом из двух песен. Вы все еще должны получить первую песню из этого массива.

Это не ответ на первоначальный вопрос, но на вашем месте я бы изменил класс, как показано ниже. Он будет более склонен хранить название песни и строки текста как отдельные атрибуты, вместо того, чтобы объединять их в виде хэша - что вроде как бросает вызов всей цели иметь Song класс.

class Song
    attr_accessor :song_name, :lyrics

    def initialize(song_name, lyrics)
       @song_name = song_name
       @lyrics = lyrics 
    end
end
Обратите внимание, что вам может не понадобиться метод get_first_line. Вы всегда можете использовать Array#first чтобы иметь тот же эффект:
real_world = Song.new("Real World", ["Line 1", "Line 2"])
puts real_world.lyrics.first # Prints "Line 1"

Вы также можете получить доступ к текстовым строкам с помощью массива индекс

puts real_world.lyrics[1] # Prints "Line 2"