1

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], oldDict)

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?

1
  • 1
    I don't fully understand your question. Is D the dictionary? Do you want the key of the dictionary to be the integer? What do you mean by "attach it do D"? Commented Nov 29, 2010 at 23:58

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

2 Comments

Gotcha2: lists:flatten/1 is super slow
Great. I never stated my question clearly. I want to change a value in a dictionary. That would be the erlang way by creating a new dictionary as you do here. NewDict = dict:store("D" ++ integer_to_list(SomeID), Value, Dict). What I want to do is name the NewDict using a passed in arg e.g. set_state({Id, Speed}) I want to name the Dict by adding the Id to e.g. D.
0

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.

1 Comment

haha. I will re-formulate it. Erlang and Alcohol could lead to brain damage.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.