如何将项列表映射到Erlang记录

时间:2015-10-21 11:11:50

标签: erlang

Erlang初学者在这里!

我有一个元素列表,我想将一些元素映射到带有记录的项目。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="POST" action="#" class="loginForm">
  <input type="text" class="loginInput username" placeholder="Aquinas Email or Number" />
  <br>
  <input type="password" class="loginInput password" placeholder="Password" />
  <br>
  <div class="checkBox">
    <input type="checkbox" id="checkBoxLink">
    <label for="checkBoxLink">Remember Me</label>
    <a href="forgotpass" class="forgotpass cfix">Forgotten your password?</a>
  </div>
  <input type="submit" value="Submit" class="login btn green" />
  <input type="reset" value="Clear Fields" class="reset btn green" />
</form>

我的记录定义如下:

List = ["a", "b", "c", "d", "e"].

我想将列表映射到与记录定义匹配的元组,以便我最终得到:

-record(a_record, { itemA = "", itemB = ""}).

我正在查看列表模块,但还没有看到干净的解决方案。

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

如果您可以保证列表中的元素与要初始化的记录字段的顺序相同,并且列表至少具有与记录具有字段相同数量的元素,则可以应用一些通过利用记录是封底下的元组这一事实,从列表中创建记录实例的hack。例如,您的a_record表示为元组,其第一个元素是原子a_record,后跟2个元素,每个记录字段一个。

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,如您所见,结果是使用a_record的值初始化List实例。

答案 1 :(得分:1)

您可以使用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]).

答案 2 :(得分:0)

我认为您进行列表理解并从映射中检索与记录中的字段关联的键实际上更安全。您可能最终会得到一个充满未定义字段的记录,但是您无需进行任何检查即可确保映射的键/值与记录的数量相同,也不必担心任何顺序。


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).

如果映射键是二进制字符串,则需要将记录字段列表中的原子转换为二进制字符串。

请注意,record_info(fields, RecordType)不是对record_info函数的有效调用。我认为这是因为record_info的返回值是在编译时确定的,因为记录本身的语法糖性质基本上是键入元组,并且运行时调用无效。