ฉันจะค้นหาภายในแฮชแถวต่างๆโดยใช้ค่าแฮชในทับทิมได้อย่างไร


234

ฉันมีแฮชหลายชุด @fathers

a_father = { "father" => "Bob", "age" =>  40 }
@fathers << a_father
a_father = { "father" => "David", "age" =>  32 }
@fathers << a_father
a_father = { "father" => "Batman", "age" =>  50 }
@fathers << a_father 

ฉันจะค้นหาอาร์เรย์นี้และส่งคืนแฮชที่บล็อกส่งคืนจริงได้อย่างไร

ตัวอย่างเช่น:

@fathers.some_method("age" > 35) #=> array containing the hashes of bob and batman

ขอบคุณ

คำตอบ:


419

คุณกำลังมองหาEnumerable # select (หรือเรียกอีกอย่างว่าfind_all):

@fathers.select {|father| father["age"] > 35 }
# => [ { "age" => 40, "father" => "Bob" },
#      { "age" => 50, "father" => "Batman" } ]

ตามเอกสารมัน "ส่งกลับอาร์เรย์ที่มีองค์ประกอบทั้งหมดของ [นับจำนวนในกรณีนี้@fathers] ซึ่งบล็อกไม่ได้เป็นเท็จ"


22
Oh! คุณเป็นคนแรก! การลบคำตอบและ +1
Milan Novota

20
โปรดทราบว่าหากคุณต้องการค้นหาเพียงรายการเดียว (รายการแรก) คุณสามารถใช้@fathers.find {|father| father["age"] > 35 }แทนได้
Leigh McCulloch

1
เป็นไปได้ไหมที่จะส่งคืนดัชนีที่พบสิ่งนี้ในอาร์เรย์แฮชดั้งเดิม
Ian Warner

1
@IanWarner ใช่ ฉันขอแนะนำให้ดูเอกสารสำหรับโมดูลที่นับได้ หากคุณยังคิดไม่ออกให้โพสต์คำถามใหม่
Jordan เริ่ม

ฉันเพิ่งทำดัชนีนี้ = ARRAY.index {| h | h [: code] == ARRAY ["code"]}
Ian Warner

198

สิ่งนี้จะส่งคืนการจับคู่ครั้งแรก

@fathers.detect {|f| f["age"] > 35 }

6
ฉันชอบสิ่งนี้มากกว่า#select- แต่ทุกอย่างเป็นไปได้สำหรับกรณีการใช้งานของคุณ #detectจะกลับมาnilถ้าไม่ตรงกับที่พบในขณะที่#selectใน @ []คำตอบของจอร์แดนจะกลับ
TJ Biddle

13
คุณสามารถใช้findแทนdetectรหัสที่อ่านได้มากขึ้น
Alter Lagos

8
findอย่างไรก็ตามอาจสร้างความสับสนในรางได้
user12341234

5
selectและdetectไม่เหมือนกันselectจะข้ามทั้งแถวในขณะที่detectจะหยุดทันทีที่พบการแข่งขันนัดแรก หากคุณกำลังมองหา ONE match @fathers.select {|f| f["age"] > 35 }.firstเทียบ @fathers.detect {|f| f["age"] > 35 } กับประสิทธิภาพและความสามารถในการอ่านการโหวตของฉันจะเป็นเช่นนั้นdetect
Naveed

35

ถ้าอาร์เรย์ของคุณดูเหมือน

array = [
 {:name => "Hitesh" , :age => 27 , :place => "xyz"} ,
 {:name => "John" , :age => 26 , :place => "xtz"} ,
 {:name => "Anil" , :age => 26 , :place => "xsz"} 
]

และคุณอยากรู้ว่าค่าบางอย่างมีอยู่แล้วในอาร์เรย์ของคุณ ใช้วิธีการค้นหา

array.find {|x| x[:name] == "Hitesh"}

สิ่งนี้จะส่งคืนวัตถุหาก Hitesh มีชื่ออื่นเป็นศูนย์


หากชื่อเป็นตัวพิมพ์เล็กเหมือน"hitesh"จะไม่ส่งคืนแฮช เราจะอธิบายถึงการใช้คำเฉพาะในกรณีเช่นนี้ได้อย่างไร
arjun

2
คุณสามารถใช้สิ่งที่ชอบ array.find {| x | x [: name] .downcase == "Hitesh" .downcase}
Hitesh Ranaut
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.