Menu
CoddyTech

Hash lồng nhau

Thuộc phần Logic và luồng xử lý trong hành trình Ruby của Coddy. Bài học 35 trên 56.

Bản thân một giá trị băm cũng có thể là một giá trị băm. Cấu trúc lồng nhau này là cách mã Ruby thường biểu diễn các bản ghi có cấu trúc: một giá trị băm duy nhất dùng id (hoặc tên) làm khóa, trong đó mỗi giá trị chứa các trường riêng:

students = {
  "Alice" => { age: 20, grade: "A" },
  "Bob"   => { age: 22, grade: "B" }
}

Để truy cập một giá trị lồng nhau, hãy nối các thao tác tra cứu:

puts students["Alice"][:age]    # 20
puts students["Bob"][:grade]    # B

Thêm một trường mới vào một trong các hash bên trong cũng tương tự:

students["Alice"][:major] = "Math"
puts students["Alice"]
# {age: 20, grade: "A", major: "Math"}

Để đọc an toàn từ một từ điển lồng nhau (nested hash) có thể thiếu khóa ở bất kỳ cấp nào, dig lần theo chuỗi và trả về nil nếu thiếu bất kỳ giá trị nào trên đường đi:

students.dig("Alice", :grade)   # "A"
students.dig("Cara",  :grade)   # nil
challenge icon

Thử thách

Trung bình

Đã cho một hash inventory lồng nhau: mỗi khóa cấp cao nhất là một phòng ban, mỗi khóa bên trong là một mặt hàng và mỗi giá trị bên trong là số lượng hàng tồn kho (một số nguyên).

Đọc một dòng đầu vào: danh sách các đường dẫn tra cứu department/item, được phân tách bằng dấu phẩy.

Với mỗi đường dẫn, theo đúng thứ tự, dùng dig để tra cứu. In ra một trong hai dòng sau:

  • <department>/<item>: <qty> khi đường dẫn tồn tại
  • <department>/<item>: missing khi dig trả về nil

Sau khi in mọi dòng, hãy in thêm một dòng tổng kết:

Total inventory: <sum>

Tổng là tổng của mọi số lượng ở tất cả các phòng ban trong hash ban đầu. Dùng vòng lặp lồng nhau, lần lượt duyệt từng phòng ban rồi từng mặt hàng.

Với đầu vào fruits/apples,meat/beef,fruits/dragonfruit,dairy/milk, đầu ra là:

fruits/apples: 12
meat/beef: 7
fruits/dragonfruit: missing
dairy/milk: 9
Total inventory: 39

Tự làm thử

inventory = {
  fruits: { apples: 12, bananas: 4 },
  meat:   { beef: 7, chicken: 5 },
  dairy:  { milk: 9, cheese: 2 }
}
lookups = gets.chomp.split(",")

# TODO: với mỗi lượt tra cứu, dùng dig rồi in ra qty hoặc 'missing'.
#       Sau đó in ra 'Total inventory: <sum>' với tổng của tất cả các mặt hàng.
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Logic và luồng xử lý

Tự luyện tập: Trình biên dịch Ruby online