2011-01-01 13 views

Odpowiedz

46
@names = ["Tom", "Harry", "John"] 
@emails = ["[email protected]", "[email protected]", "[email protected]"] 

@list = @names.zip(@emails) 
#=> [["Tom", "[email protected]"], ["Harry", "[email protected]"], ["John", "[email protected]"]] 

@list.each do |name,email| 
    # When a block is passed an array you can automatically "destructure" 
    # the array parts into named variables. Yay for Ruby! 
    p "#{name} <#{email}>" 
end 
#=> "Tom <[email protected]>" 
#=> "Harry <[email protected]>" 
#=> "John <[email protected]>" 

@urls = ["yahoo.com", "ebay.com", "google.com"] 

# Zipping multiple arrays together 
@names.zip(@emails, @urls).each do |name,email,url| 
    p "#{name} <#{email}> :: #{url}" 
end 
#=> "Tom <[email protected]> :: yahoo.com" 
#=> "Harry <[email protected]> :: ebay.com" 
#=> "John <[email protected]> :: google.com" 
+4

Aha! Więc * to * jest tym, czym jest "zip"! Jakoś nigdy tak naprawdę nie wszedł do mojego standardowego zestawu narzędzi. Miły. +1 – Matchu

+0

Czy to rozwiązanie będzie nadal stosowane Dodałem kolejną zmienną instancji o nazwie @urls = ["yahoo.com", "ebay.com", "google.com"]. – lou1221

+0

@ lou1221 Tak; zobacz zaktualizowaną odpowiedź powyżej. 'Array # zip' może przyjąć dowolną liczbę argumentów. – Phrogz

3

Można użyć zip spięcia razem dwóch tablic i następnie map stworzyć Item obiektów z nazwy-email par. Zakładając, że masz klasę Item którego initialize metody akceptuje hash, kod wyglądałby następująco:

@list = @names.zip(@emails).map do |name, email| 
    Item.new(:name => name, :email => email) 
end 
7
Hash[*names.zip(emails).flatten] 

To daje hash z name => E-mail.

+1

Działa w tej sytuacji, ale przyszłe czytniki uwaga: nie jest to rozwiązanie ogólne, ponieważ jeśli "nazwy" lub "e-maile" były tablice, które zawierały tablice, "spłaszczać" uruchomiłoby rekursywnie. – Matchu

+5

Pod Ruby 1.9 możesz po prostu: 'Hash [names.zip (e-maile)]' – Phrogz

+2

spłaszczyć (1) zapobiegnie rekurencji, jeśli chcesz. –

15

Wystarczy być różne:

[@names, @emails, @urls].transpose.each do |name, email, url| 
    # . . . 
end 

Jest to podobne do tego, co robi Array#zip tą różnicą, że w tym przypadku nie będzie żadnych nil wyściółka krótkich wierszy; jeśli czegoś brakuje, zostanie zgłoszony wyjątek.

+5

Wskazówka dotycząca transpozycji jest świetna. Dzięki za opublikowanie tego – lou1221

+1

szukałem 'zip (* tablic) Pythona'. To jest to! – Droogans