2009-12-12 45 views
13

Tôi không có ý tưởng nếu đây là một vấn đề Hash hoặc một vấn đề mảng, nhưng tôi không tìm ra lý do tại sao dấu hoa thị (*) được yêu cầu trong ví dụ thứ ba để có được một băm đầy dữ liệu. Không có nó, nó sẽ xuất ra một băm rỗng.Tại sao tôi cần dấu hoa thị trước một mảng?

# -*- coding: utf-8 -*- 
require 'pp' 
pp [[:first_name, 'Shane'], [:last_name, 'Harvie']] 
# => [[:first_name, "Shane"], [:last_name, "Harvie"]] 

pp [[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten 
# => [:first_name, "Shane", :last_name, "Harvie"] 

pp Hash[*[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten] 
# => {:first_name=>"Shane", :last_name=>"Harvie"} 

pp Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten] 
# => {} 

Dưới đây là giải thích về phương pháp.

--------------------------------------------------------------- Hash::[] 
    Hash[ [key =>|, value]* ] => hash 

    From Ruby 1.8 
------------------------------------------------------------------------ 
    Creates a new hash populated with the given objects. Equivalent to 
    the literal +{ _key_, _value_, ... }+. Keys and values occur in 
    pairs, so there must be an even number of arguments. 

     Hash["a", 100, "b", 200]  #=> {"a"=>100, "b"=>200} 
     Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200} 
     { "a" => 100, "b" => 200 }  #=> {"a"=>100, "b"=>200} 

Trả lời

30

Nhà điều hành splat (có nghĩa là, các *) biến những gì nếu không sẽ là một mảng vào danh sách chuyển nhượng trong băm. Bạn phải cung cấp cho toán tử [] một danh sách thực tế để chuyển thành các cặp khóa/giá trị của băm. (Xem bên dưới để có một liên kết đến một mô tả ngắn về toán tử splat thực sự có thể làm điều này (bung một mảng vào danh sách) hoặc ngược lại (thu thập một danh sách thành một mảng).)

Cách bạn đã làm ở trên , bạn cung cấp cho Hash[]một số lẻ các mục, cụ thể là một mảng duy nhất. (Hãy suy nghĩ về những gì [[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten sản xuất. Nó mang lại [:first_name, 'Shane', :last_name, 'Havie'].) Khi tài liệu bạn trích dẫn nói, nhà điều hành [] phải có số lượng phần tử đồng đều. Lưu ý rằng sau (mặc dù vô dụng) không công việc:

>> Hash[[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten, 1] 
=> {[:first_name, "Shane", :last_name, "Harvie"]=>1} 

(Đó là chưa rõ ràng với tôi lý do tại sao bạn không nhận được "số lẻ của các đối số cho Hash" báo lỗi khi sử dụng mã bạn có trên - như bạn làm gì nếu bạn thử Hash[1].)

Ví dụ đơn giản hơn có thể làm cho nó rõ ràng hơn. Đầu tiên, đi qua một mục, một mảng. Việc mở lên mảng với * bàn Hash[] một danh sách các mục:

>> Hash[['foo', 'bar', 'bizz', 'buzz']] 
=> {} 
>> Hash[*['foo', 'bar', 'bizz', 'buzz']] 
=> {"foo"=>"bar", "bizz"=>"buzz"} 

Xem this blog post cho một lời giải thích đầy đủ hơn. Bạn cũng có thể tìm thấy this short write-up about the splat operator hữu ích.

+0

Cảm ơn bạn rất nhiều vì đã giải thích chi tiết và liên kết. Bây giờ tôi hoàn toàn hiểu điều này là gì. Bây giờ mọi thứ đều có ý nghĩa. –

Các vấn đề liên quan