Как превратить список пар кортежей в запись в Erlang? - PullRequest
4 голосов
/ 17 мая 2009

Допустим, у меня есть это:

-record(my_record, {foo, bar, baz}).

Keyvalpairs = [{foo, val1},
               {bar, val2},
               {baz, val3}].

Foorecord = #my_record{foo=val1, bar=val2, baz=val3}.

Как мне преобразовать пары ключей в Foorecord?

Ответы [ 3 ]

17 голосов
/ 17 мая 2009

Самое простое, что нужно сделать:

Foorecord = #my_record{foo=proplists:get_value(foo, Keyvalpairs), 
      bar=proplists:get_value(bar, Keyvalpairs),
      baz=proplists:get_value(baz, Keyvalpairs)}.

Если это слишком повторяющееся, вы можете сделать что-то вроде:

Foorecord = list_to_tuple([my_record|[proplists:get_value(X, Keyvalpairs)
      || X <- record_info(fields, my_record)]]).
3 голосов
/ 29 сентября 2013

Как и в других ответах, вам нужно найти собственное решение для достижения этой цели. Предлагаемые решения, однако, являются неполными. Например, он не учитывает значения по умолчанию для записей записей. Я использую следующий фрагмент кода, чтобы позаботиться об этом преобразовании:

%% @doc returns a "RECSPEC" that can be used by to_rec in order to 
%% perform conversions
-define(RECSPEC(R), {R, tuple_to_list(#R{}), record_info(fields, R)}).

%% @doc converts a property list into a record.
-spec to_rec(recspec(), proplist()) -> record().
to_rec({R, [_ | N], Spec}, P) when is_atom(R) and is_list(Spec) ->
    list_to_tuple(
      [R | lists:foldl(
         fun ({K,V}, A) ->
             case index_of(K, Spec) of
                 undefined -> 
                     A;
                 I -> 
                     {Head, Tail} = lists:split(I, A),
                      Rest = case Tail of
                                [_ | M] -> M;
                                []      -> []
                            end,
                     Head ++ [V | Rest]
             end
         end, N, P)]).

Теперь можно просто сделать:

-record(frob, {foo, bar="bar", baz}).

to_rec(?RECSPEC(frob), [{baz, "baz"}, {foo, "foo"}])

, что дает

#frob{foo="foo", bar="bar", baz="baz"}

Я поместил это в небольшую библиотеку «инструментов», которую я собираю, чтобы собрать эти маленькие «фрагменты», которые просто облегчают жизнь при разработке приложений на Erlang: ETBX

0 голосов
/ 17 октября 2010

Если у вас есть значения в том же порядке, что и в записи, вы можете конвертировать непосредственно в запись, вам просто нужно предшествовать имени записи в первом элементе списка и затем преобразовать список в кортеж .

Foorecord = list_to_tuple([my_record]++[Val || {_,Val} <- [{foo, val1},{bar, val2},{baz, val3}] ]).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...