二郎初来乍到!我有一个元素列表,我想将其中的一些元素Map到具有记录的项。
List = ["a", "b", "c", "d", "e"].
我还有一条记录定义如下:
-record(a_record, { itemA = "", itemB = ""}).
我想将列表Map到与记录定义匹配的元组中,这样我就得到了:
#a_record{itemA="A", itemB="B" }.
我正在查看列表模块,但还看不到一个干净的解决方案。谢谢你的帮助!
cpjpxq1n1#
如果您可以保证列表中的元素与要初始化的记录字段的顺序相同,并且列表中的元素数至少与记录中的字段数相同,那么您可以利用记录是隐藏在表中的元组这一事实,通过一些技巧从列表中创建记录的示例。例如,您的a_record表示为一个元组,其第一个元素是原子a_record,后跟2个元素,每个元素对应一个记录字段。
a_record
1> List = ["a", "b", "c", "d", "e"]. ["a","b","c","d","e"] 2> rd(a_record, { itemA = "", itemB = ""}). a_record 3> ARecord = list_to_tuple([a_record|lists:sublist(List,size(#a_record{})-1)]). #a_record{itemA = "a",itemB = "b"}
命令1定义了我们的List,在命令2中,我们使用shell命令rd定义了一个记录,就像您的问题中的记录一样。命令3构建了一个新的列表,该列表由记录名作为头部,字段初始化器作为尾部组成。size/1函数为我们提供了记录中的字段数(包括其名称)。因此我们将其减去1,并将得到的值作为List的子列表的大小,用于初始化记录字段。然后,我们将得到的列表传递给list_to_tuple/1,正如您所看到的,结果是一个用List中的值初始化的a_record示例。
List
rd
size/1
list_to_tuple/1
1yjd4xko2#
您可以使用record_info/2和list_to_tuple/1:
List = ["a", "b", "c", "d", "e"], List2 = [string:to_upper(P) || P <- lists:sublist(List, record_info(size, a_record)-1)], list_to_tuple([a_record | List2]).
rggaifut3#
我认为更安全的做法是执行列表解析,并从Map中检索与记录中的字段相关联的键。您可能会得到一个充满未定义字段的记录,但您不需要做任何检查来确保Map与记录具有相同数量的键/值,也不需要关心任何顺序。
RecordType = a_record. RecordFields = record_info(fields, a_record). Map = #{a_record_field => <<"a record value">>}. Record = map_to_record(Map, RecordType, RecordFields). map_to_record(Map, RecordType, RecordFields) -> RecordValues = [maps:get(RecordField, Map, undefined) || RecordField <- RecordFields], AlmostRecord = [RecordType | RecordValues], list_to_tuple(AlmostRecord).
如果Map键是二进制字符串,那么需要将记录字段列表中的原子转换为二进制字符串。值得注意的是,record_info(fields, RecordType)不是对record_info函数的有效调用。我认为这是因为record_info的返回值是在编译时确定的,因为记录本身基本上是类型化元组的语法糖性质,运行时调用是无效的。
record_info(fields, RecordType)
record_info
3条答案
按热度按时间cpjpxq1n1#
如果您可以保证列表中的元素与要初始化的记录字段的顺序相同,并且列表中的元素数至少与记录中的字段数相同,那么您可以利用记录是隐藏在表中的元组这一事实,通过一些技巧从列表中创建记录的示例。例如,您的
a_record
表示为一个元组,其第一个元素是原子a_record
,后跟2个元素,每个元素对应一个记录字段。命令1定义了我们的
List
,在命令2中,我们使用shell命令rd
定义了一个记录,就像您的问题中的记录一样。命令3构建了一个新的列表,该列表由记录名作为头部,字段初始化器作为尾部组成。size/1
函数为我们提供了记录中的字段数(包括其名称)。因此我们将其减去1,并将得到的值作为List
的子列表的大小,用于初始化记录字段。然后,我们将得到的列表传递给list_to_tuple/1
,正如您所看到的,结果是一个用List
中的值初始化的a_record
示例。1yjd4xko2#
您可以使用record_info/2和list_to_tuple/1:
rggaifut3#
我认为更安全的做法是执行列表解析,并从Map中检索与记录中的字段相关联的键。您可能会得到一个充满未定义字段的记录,但您不需要做任何检查来确保Map与记录具有相同数量的键/值,也不需要关心任何顺序。
如果Map键是二进制字符串,那么需要将记录字段列表中的原子转换为二进制字符串。
值得注意的是,
record_info(fields, RecordType)
不是对record_info
函数的有效调用。我认为这是因为record_info
的返回值是在编译时确定的,因为记录本身基本上是类型化元组的语法糖性质,运行时调用是无效的。