开发者

Adding a parameter when naming a variable

开发者 https://www.devze.com 2023-01-27 07:05 出处:网络
I would like to create a dictionary for each Identification number. The argument passed in could be e.g. {Id, Key, Value}

I would like to create a dictionary for each Identification number.

The argument passed in could be e.g. {Id, Key, Value}

I want to create a new dictionary by appending the Id to a prefix e.g. Dict

Then I want to write the Key to the dict using dict:store(Key, [Value], old开发者_如何学GoDict)

The Value at this point is a queue, so I will first read the queue and add to it then write back to the dictionary.

My question is how does the Id get appended to the prefix?


You want to construct a variable name at runtime

That's impossible, sorry.

In Erlang, you cannot attach names to things at runtime. Your only option would be store all dictionaries in another dictionary and passing that around.

For glueing together a static identifier (D) and a number, Erlang gives you quite a number of possibilities. The easiest way would be to construct a tuple {d, ID} and using that as the key. You can also use any of the string concatentation methods described below.

Now that you've clarified your question, most of my original interpretations have lost context. I'm leaving them here, anyway.

You want to concatenate a string and an integer

This is easy, just use:

"D" ++ integer_to_list(SomeID)

You want to set a value in a dictionary, using the above as the key

Erlang is a functional language, so destructively modifiying a dictionary is not possible. Supposing you have a dictionary stored in the variable Dict and SomeID is set to three. You can obtain a copy of Dict in which "D3" is set to Value using:

NewDict = dict:store("D" ++ integer_to_list(SomeID), Value, Dict)

You are looking for a printf-like mechanism

The Erlang function io_lib:format(FmtString, Args) can be used for that. Unlike printf, formatting directives start with a tilde character. You can look up the right directive in the manual, but for adding an integer to the string "D", the call would look like this:

io_lib:format("D~b", [SomeID])

Gotcha: io_lib:format/2 returns a deep list of characters. If you want a flat list, use lists:flatten/1 on the result. You can try this in the Erlang shell:

(b@frog)1> SomeID = 3.
3                                   
(b@frog)2> io_lib:format("D~b", [SomeID]).
[68,"3"] 
(b@frog)3> lists:flatten(io_lib:format("D~b", [SomeID])).
"D3"


† actually, you can do that using the process dictionary. Don't! You'll lose the ability to properly test and debug your program (apart from going to hell).


The dict structure in Erlang doesn't allow you to give it a name. And it's probably pointless to have a name in a dict. A dict is a mere key/value dictionary, whose representation is not defined.

If you have multiple dictionaries that you want to refer to, it's probably a good idea to store them in a record or in a tuple, to "name" them. You shouldn't create variable names out of function parameters.

{my_dict, Dict}

#state{
  my_dict = Dict
}

Supposing you need to have the dictionary names as d_mycustomname, you could write something like:

atomize(Name) ->
  list_to_atom("d_" ++ Name).

As the other respondents, I'm not sure this is exactly what you've asked for. Please re-formulate your question to get better answers. My answer at this point is just guess-work driven by alcohol.

AFTER YOUR UPDATE:

Regarding the way you add values to the dictionary, what you want is probably an update and not a store operation.

enqueue(D, {_Id, Key, Value}) ->
    Update = fun (Old) -> Old ++ [Value] end,
    dict:update(Key, Update, [Value], D).

That will append your value to the "queue". If not present yet, it will create one.

Regarding the prefixed names, you may store your dictionaries in a proplist:

enqueue(ListOfDicts, {Id, Key, Value}) ->
    Name = "dict_" ++ Id,
    case proplists:get_value(Name, ListOfDicts) of
      undefined -> % No such a dict yet
        [{Name, dict:new()}|ListOfDicts];
      D ->
        Update = fun (Old) -> Old ++ [Value] end,
        NewD = dict:update(Key, Update, [Value], D),
        lists:keyreplace(Name, 1, ListOfDicts, {Name, NewD})
    end.

I didn't test the code, this is just t give you an idea about what I'm suggesting.

0

精彩评论

暂无评论...
验证码 换一张
取 消