2017-04-13 3 views
0

関数を定義するにはどうすればいいですか?引数として文字列を取り、レコードのメンバーを返します。 記録関数の文字列=> erlangのレコードメンバー

-record(measurement, { temperature, pm2p5, pm10, pressure, humidity, others=[]}). 

そして、私の機能の断片と例えば:

update_measurement(Measurement, Type_as_String, Value) -> 
    Measurement#measurement{get_type(Type_as_String) = Value} 

私は文字列としてタイプを渡すことにより、値を更新したい、と私は定義するためのアイデアを持っていません機能get_type(Type_as_String)。 私は原子で試しましたが、うまくいきませんでした。私は他の関数で、このパターンを再利用したいので

update_measurement(Measurement, Type_as_String, Value) -> 
    case Type_as_String of 
     "temperature" -> Measurement#measurement{temperature = Value}; 
     "humidity" -> Measurement#measurement{humidity = Value}; 
... 

よう

何かが、OKではありません。

+0

あなたは 'binary_to_atom'を意味しますか?しかし、実際それは私にはちょっと変わったようです。代わりにすべてのマッチャーを書くことはできませんか? – raina77ow

+0

いいえ、 'get_type(Type_as_String) - > " temperature " - > temperature;を定義しました。 "湿度" - >湿度; .... 'が動作しませんでした – przem

+0

申し訳ありません、それを取得しないでください:あなたの文字列はバイナリまたはリストですか?後者の場合( '' temperature "')、代わりに 'list_to_atom/1'を使います。 'list_to_atom(" temperature ")=> temperature'と同じです。 – raina77ow

答えて

2

パフォーマンスがあなたの最大の関心事ではない場合:

update_measurement(Measurement, Type_as_String, Value) -> 
    update_field(Measurement, Type_as_String, Value). 

update_field(#measurement{} = Record, SKey, Value) -> 
    update_field(Record, SKey, Value, record_info(fields, measurement)); 
% add other records here 
update_field(_, _, _) -> error(bad_record). 

update_field(Record, SKey, Value, Fields) -> 
    update_field(Record, list_to_existing_atom(SKey), Value, Fields, 2). 

update_field(Record, Key, Value, [Key|_], N) -> 
    setelement(N, Record, Value); 
update_field(Record, Key, Value, [_|Fields], N) -> 
    update_field(Record, Key, Value, Fields, N+1); 
update_field(_, _, _, [], _) -> 
    error(bad_key). 

record_info/2は本当の関数ではありませんが、あなたは、コンパイル時定数としてmeasurementを提供する必要があります。