如何从元组列表创建记录
How to create record from tuple list
如何从下面的元组列表((字符串*字符串)列表)创建记录(t)?
From: [("field1", "foo"); ("field2", "bar"); ("field3", "baz")]
To: { field1: "foo"; field2: "bar"; field3: "baz" }
我可以使用可变字段来实现,如下所示,但还有其他方法吗?
type t = {
mutable key1: string;
mutable key2: string;
mutable key3: string;
}
let set (key, value) item =
match key with
| "key1" -> item.key1 <- value; item
| "key2" -> item.key2 <- value; item
| "key3" -> item.key3 <- value; item
| _ -> item
let to_rec list =
let rec aux acc = function
| [] -> acc
| h :: t -> aux (set h acc) t
in
aux { key1 = ""; key2 = ""; key3 = "" } list
一个列表可以包含任意数量的元素或none。记录类型恰好包含一定数量的字段。我略有根据的猜测是 Hashtbl.
会更好
我们可以很容易地编写一个函数,该函数将获取一个列表并根据其内容创建一个散列 table。
let convert_to_hash lst =
let rec aux h = function
| [] -> h
| (k, v)::xs -> (Hashtbl.add h k v; aux h xs)
in
aux (Hashtbl.create 20) lst
如果我们在您的示例数据上调用它:
let h = convert_to_hash [("field1", "foo"); ("field2", "bar"); ("field3", "baz")]
然后遍历那个散列table,我们可以看到结果:
utop # Hashtbl.iter (Printf.printf "%s => %s\n") h;;
field1 => foo
field3 => baz
field2 => bar
- : unit = ()
您可能还想用 Map 实现这种功能,但考虑到您的所有记录字段都标记为 mutable,Hashtbl 在这种情况下可能更合适.
不需要使用可变字段,您可以使用with
来更新记录的字段,例如
let of_list = List.fold_left (fun r (k,v) ->
match k with
| "field1" -> {r with field1=v}
| "field2" -> {r with field2=v}
| "field3" -> {r with field2=v}
| s -> invalid_arg ("an unexpected field " ^ s))
{field1=""; field2=""; field3=""}
当您有预定义的输入语法时,即您确定列表中的字段将按特定顺序排列(或者您只是对它们进行排序),您可以直接在列表的结构上进行模式匹配,例如,
let of_list = function
| ["field1", field1;
"field2", field2;
"field3", field3] -> {field1; field2; field3}
| _ -> invalid_arg "expected the predefined structure"
最后,如果性能不是很重要,可以使用List.assoc
查询字段,例如
let of_list elts = {
field1 = List.assoc "field1" elts;
field2 = List.assoc "field2" elts;
field3 = List.assoc "field3" elts;
}
如何从下面的元组列表((字符串*字符串)列表)创建记录(t)?
From: [("field1", "foo"); ("field2", "bar"); ("field3", "baz")]
To: { field1: "foo"; field2: "bar"; field3: "baz" }
我可以使用可变字段来实现,如下所示,但还有其他方法吗?
type t = {
mutable key1: string;
mutable key2: string;
mutable key3: string;
}
let set (key, value) item =
match key with
| "key1" -> item.key1 <- value; item
| "key2" -> item.key2 <- value; item
| "key3" -> item.key3 <- value; item
| _ -> item
let to_rec list =
let rec aux acc = function
| [] -> acc
| h :: t -> aux (set h acc) t
in
aux { key1 = ""; key2 = ""; key3 = "" } list
一个列表可以包含任意数量的元素或none。记录类型恰好包含一定数量的字段。我略有根据的猜测是 Hashtbl.
会更好我们可以很容易地编写一个函数,该函数将获取一个列表并根据其内容创建一个散列 table。
let convert_to_hash lst =
let rec aux h = function
| [] -> h
| (k, v)::xs -> (Hashtbl.add h k v; aux h xs)
in
aux (Hashtbl.create 20) lst
如果我们在您的示例数据上调用它:
let h = convert_to_hash [("field1", "foo"); ("field2", "bar"); ("field3", "baz")]
然后遍历那个散列table,我们可以看到结果:
utop # Hashtbl.iter (Printf.printf "%s => %s\n") h;;
field1 => foo
field3 => baz
field2 => bar
- : unit = ()
您可能还想用 Map 实现这种功能,但考虑到您的所有记录字段都标记为 mutable,Hashtbl 在这种情况下可能更合适.
不需要使用可变字段,您可以使用with
来更新记录的字段,例如
let of_list = List.fold_left (fun r (k,v) ->
match k with
| "field1" -> {r with field1=v}
| "field2" -> {r with field2=v}
| "field3" -> {r with field2=v}
| s -> invalid_arg ("an unexpected field " ^ s))
{field1=""; field2=""; field3=""}
当您有预定义的输入语法时,即您确定列表中的字段将按特定顺序排列(或者您只是对它们进行排序),您可以直接在列表的结构上进行模式匹配,例如,
let of_list = function
| ["field1", field1;
"field2", field2;
"field3", field3] -> {field1; field2; field3}
| _ -> invalid_arg "expected the predefined structure"
最后,如果性能不是很重要,可以使用List.assoc
查询字段,例如
let of_list elts = {
field1 = List.assoc "field1" elts;
field2 = List.assoc "field2" elts;
field3 = List.assoc "field3" elts;
}