模組:Get/doc
更多語言
更多操作
此頁面為 Module:Get 的說明文件
本模塊靈感來源於JSONPath。
假設有這樣一個數據:
data = {
store = {
books = {
{
category = "reference",
author = "Nigel Rees",
title = "Sayings of the Century",
price = 8.95
},
{
category = "fiction",
author = "Evelyn Waugh",
title = "Sword of Honour",
price = 12.99
},
{
category = "fiction",
author = "Herman Melville",
title = "Moby Dick",
isbn = "0-553-21311-3",
price = 8.99
},
{
category = "fiction",
author = "J. R. R. Tolkien",
title = "The Lord of the Rings",
isbn = "0-395-19395-8",
price = 22.99
}
},
bicycle = {
color = "red",
price = 399
}
}
}
用法:
> local get = require('Module:Get')
> -- 获取data.store.books的所有子项的author(JSONPath:$.store.books[*].author)
> get(data).store.books:items().author()
{"Nigel Rees", "Evelyn Waugh", "J. R. R. Tolkien", "J. R. R. Tolkien"}
> -- 获取data内任意深度的author(JSONPath:$..author)
> get(data)._.author()
{"Nigel Rees", "Evelyn Waugh", "J. R. R. Tolkien", "J. R. R. Tolkien"}
> -- 获取data.store内任意深度的price(JSONPath:$.store..price)
> get(data).store._.price()
{8.95, 12.99, 8.99, 22.99, 399}
> -- 获取data.store内任意深度的books的第3个子项(JSONPath:$..book[2])
> get(data)._.books[3]()
{{ category = "fiction", author = "Herman Melville", title = "Moby Dick", isbn = "0-553-21311-3", price = 8.99 }}
> -- 获取data内任意深度的books的子项中满足price < 10的项目(JSONPath:$..books[[email protected]<10]
> get(data)._.books[function (x) return x.price < 10 end]()
{
{ category = "reference", author = "Nigel Rees", title = "Sayings of the Century", price = 8.95 },
{ category = "fiction", author = "Herman Melville", title = "Moby Dick", isbn = "0-553-21311-3", price = 8.99 },
}
get(...)
get(...)返回一個Getter對象,可以傳多個值。
> get(data)._.author()
{"Nigel Rees", "Evelyn Waugh", "J. R. R. Tolkien", "J. R. R. Tolkien"}
> get(data, { author = "Foo" }, { bar = { author = "Bar" } })._.author()
{"Nigel Rees", "Evelyn Waugh", "J. R. R. Tolkien", "J. R. R. Tolkien", "Foo", "Bar"}
特別地,對於get函數返回的Getter對象,它迭代時將依次返回每個非nil參數,因此你可以這樣用get函數:
for v in get('a', 'b', nil, 'd') do -- 或 get('a', 'b', nil, 'd'):generate()
print(i, v)
end
--[[ 输出:
a
b
d
]]
方法
每個Getter對象都有以下方法:
非鏈式調用方法
:all()
返回一個包含查找到的值的列表。該列表具有table庫的方法,以及一個字段n表示列表長度。
> get(data).store.books:items().author:all()
> get(data).store.books:items().author() -- 简写,建议仅在整个表达式写在一行时使用
{"Nigel Rees", "Evelyn Waugh", "J. R. R. Tolkien", "J. R. R. Tolkien"}
> get(data).store.books:items().author:all():concat(" & ")
Nigel Rees & Evelyn Waugh & J. R. R. Tolkien & J. R. R. Tolkien
:one()
返回結果中的第一個值,如果不存在則返回nil。
> get(data).store.books:items().author:one()
"Nigel Rees"
:must_one([message])
返回結果中的第一個值,如果不存在則報錯。
> get(data).store.books:items().author:one()
"Nigel Rees"
:unpack()
解包,類似Lua標準庫的unpack(在5.2及以上版本中為table.unpack)。
> get(data).store.books:items().author:unpack()
"Nigel Rees", "Evelyn Waugh", "J. R. R. Tolkien", "J. R. R. Tolkien"
:iterate()
:all()返回的是一個包含了所有結果的列表,而:iterate()的返回值能用於for循環。
-- 第一个值必须忽略,即`_`,它存储了内部信息,使用者完全用不上这个值
for _, author in get(data).store.books:items().author:iterate() do print(author) end
-- `:iterate()` 可以省略且推荐省略,上下两行代码等价
for _, author in get(data).store.books:items().author do print(author) end
--[[ 输出:
Nigel Rees
Evelyn Waugh
J. R. R. Tolkien
J. R. R. Tolkien
]]
:generate()
返回一個迭代器函數,每次調用將得到下一個結果,直到所有結果都返回(該迭代器是有副作用的,即非純函數的)。該方法與:iterate()類似,可用於for循環,區別是該方法返回的迭代器函數不會輸出內部狀態。
在且僅在for循環中,:generate()可以省略,更推薦省略,除非查詢結果(注意是查詢結果而不是待查數據)有非常多,多到影響性能。
for author in get(data).store.books:items().author:generate() do print(author) end
for author in get(data).store.books:items().author do print(author) end -- 省略:generate()
--[[ 输出:
Nigel Rees
Evelyn Waugh
J. R. R. Tolkien
J. R. R. Tolkien
]]
鏈式調用方法
鏈式調用方法將返回一個Getter對象。
:field(key)
獲取字段的值,一般不需要用這個方法,直接.xxx即可。而當字段的鍵為'_'或函數時,只有調用此方法才能獲取到該鍵對應的值,因為'_'被「獲取任意深度的值」的語法占用(如get(data).store._.price),後者被filter的簡寫占用。
local data = {
_ = {
foo = 'A',
},
another = {
bar = {
foo = 'B',
},
},
}
get(data)._.foo() --> {'A', 'B'}
get(data):field('_').foo() --> {'A'}
:filter(predict)
過濾。
> get(data)._.books:items():filter(function (x) return x.price < 10 end).title()
> get(data)._.books[function (x) return x.price < 10 end].title() -- 这是一个针对数组的简写,与上面等价
{"Sayings of the Century", "Moby Dick"}
> get(data)._:filter(function (x) return type(x) == "number" end)()
{8.95, 12.99, 8.99, 22.99, 399}
:items([filter])
獲取列表的每個項目。如果filter參數不為空,則相當於:items():filter(filter)。
> get(data).store.books:items().author()
{"Nigel Rees", "Evelyn Waugh", "J. R. R. Tolkien", "J. R. R. Tolkien"}
:values([filter])
獲取表的每個值,包括列表部分和字典部分。如果filter參數不為空,則相當於:values():filter(filter)。
> get(data).store.books[1]:values()()
{"reference", "Nigel Rees", "Sayings of the Century", 8.95}
:map(mapper)
轉換每個數據。
> for _, lowered_title in get(data)._.title:map(function (title) return title:lower() end) do print(lowered_title) end
sayings of the century
sword of honour
moby dick
the lord of the rings