Ruby 小技巧(一) - 使用 dig 获取嵌套 Hash 和 Array 的数据

环境

  • Ruby: 3.0.1

  • Ruby On Rails: 6.1.4

dig 是什么

dig 是 Ruby 提供的获取数组和哈希里边值的方法,支持嵌套方式的获取

# Hash
user = {
	name: "ian",
	address: {
		province: "广东省"
	}
}

user.dig(:name)	# => "ian"

# 获取嵌套的的数据
user.dig(:address)	# => "address"
user.dig(:address, :province)	# => "广东省"

# 如果查找的过程中遇到 nil,将会直接返回 nil,不继续往下查询
# 下面试图获取不存在的键 profile
user.dig(:profle)	# => nil
user.dig(:profile, :avatar)	# => nil

# 注意:如果前面一层找到的数据不是哈希或数组,后边的查找会报错
user.dig(:name)	# => "ian"
user.dig(:name, :firstname)	# => TypeError: String does not have #dig method

# Array,由于在数组的表现跟哈希一致,只是把 key 换成了 index,所以不多赘述
arr = ["a", "b", ["c", "d"]]

arr.dig(0)	# => "a"

arr.dig(2)	# => ["c", "d"]
arr.dig(2, 0)	# => "c"

arr.dig(3)	# => nil
arr.dig(3, 0)	# => nil

arr.dig(0)	# => "a"
arr.dig(0, 1)	# => TypeError: String does not have #dig method

性能

Ruby 2.3 dig Method - Thoughts and Examples 这篇文章中有相关的性能测试。在里边的给定的测试案例下,使用dig相比于默认的[]方式获取数据会有一定的性能损耗,最坏的情况是使用dig的耗时是[]的 1.5 倍,但也足够快了,每秒能处理 600 万次操作。

其他使用场景

定义嵌套数据的默认值

# 假设要获取配置中的 database 中的 host ,如果没有则使用默认值
config = {}
host = config.dig(:database, :host) || "127.0.0.1" # => "127.0.0.1"

写在最后

文章内容错误的地方,欢迎及时指出。

最後までご覧いただいてありがとうございます

Ruby 小技巧系列

评论