[英]Elixir searching an ETS table
我有一些元組存儲在 Elixir :ets 表中,格式如下,
{id, "first_name", "last_name"}
我正在尋找在給定搜索詞的名字和姓氏上搜索 ETS 表。 例如,如果某人的名字是 Alice,則搜索將返回“Al”、“Ali”、“Alic”等元組。
到目前為止,我已經嘗試過:
:ets.match_object(table_name, {:_, :_, "last_name"})
當它與“last_name”完全匹配時有效,但如果我在搜索字符串中有“last”或一些較短的排列,它不會返回結果。
我還研究了搜索向量、ets.match、ets.lookup 和其他一些執行搜索的方法。 是否有一些內置的或其他 Elixy 方式來進行這種類型的字符串搜索?
請記住,您在 Erlang 中有通用比較規則,這意味着您可以比較字符串"Alice"
和"Al"
因為它們只是列表。
現在到有趣的部分:
table = :ets.new(:table, [:protected, :set])
:ets.insert(table, {1, "Alice", "Dannings"})
:ets.insert(table, {2, "Ali", "Aaqib"})
:ets.insert(table, {3, "Bob", "Dannings"})
:ets.insert(table, {4, "Amanda", "Clarke"})
:ets.insert(table, {5, "Al", "Clarke"})
# now let's explore elixir comparison rules
"Alice" >= "Al"
"Alice" < "Am"
# based on rules above we can make a selector which will be equivalent to starts_with?
selector = :ets.fun2ms(
fn({_, x, _} = y) # match all three element tuples
when # where
x >= "Al" and x < "Am" # second element is greater or equal to "Al" and less than "Am" ("m" is the next letter in the alphabet)
-> y end)
:ets.select(table, selector)
#[{1, "Alice", "Dannings"}, {2, "Ali", "Aaqib"}, {5, "Al", "Clarke"}]
盡管您可以通過字符串的開頭進行“搜索”,但這很棘手。
人們可能會使用ets
查找的:ets.foldl/3
, :ets.foldl/3
。
:ets.foldl(fn
{_, "Al" <> _, _} = y, acc -> [y | acc] # firstname
{_, _, "Al" <> _} = y, acc -> [y | acc] # lastname
_, acc -> acc # no match
end, [], table)
請注意,與@MikhailAksenov 提出的解決方案相比,這效率較低,因為搜索是在調用過程中完成的,因此所有數據都必須在那里傳輸,而不是在ets
“內部”過濾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.