[erlang-questions] Update with complicated data structure

Dmitry Kolesnikov dmkolesnikov@REDACTED
Mon Nov 23 21:44:50 CET 2015


Hello,

One of the Erlang power is pattern match and recursions.
I would look on the following suggestion for educational purposes:

update_price([#company_info{company_id = Id, consumption = C}=Head | Tail], Id, Price) ->
   [Head#company_info{consumption = C + Price} | Tail];

update_price([Head | Tail], Id, Price) ->
   [Head | update_price(Tail, Id, Price)].


In real-life, you might look on some data structures to hold on your data set.

Best Regards, 
Dmitry


> On Nov 23, 2015, at 12:06 PM, YuanZhiqian <on-your-mark@REDACTED> wrote:
> 
> Hi Guys,
> 
>   Sorry to bother you again... I am totally a green hand in Erlang :(
> 
>   Here is the problem I am now struggling with: in C&C++, we are always able to update a field in an object simply using obj.field1 = Value; But in Erlang, since its once-bound-never-change policy, people would have to find a way around to achieve the same goal, and things are getting worse when the data structure is a little more complicated, which is my case:
> 
>   I have a list of records, whose definition is as follows
> 
> -record(company_info, {
>         company_id,
>         budget,
>         consumption,
>         compaign_ids
>     }).
> 
> What I want to do is to add a value to the consumption of the record whose company_id is given, and returning error message if there's no such record found. Written in C, that would be:
> 
> ///////////////////////////////////In C&C++///////////
> CompanyInfo co_list[1000];
> /* initialized somewhere else ... */
> 
> for (size_t i = 0; i < 1000; ++i) {
>   if (co_list[i].comany_id == co_id) {
>     co_list[i].consumption += price;  
>     break;
>   }
> }
> 
> if (i == 1000)
>   err_msg = "bla...";
> //////////////////////////////////////////////////////
> 
> But in Erlang, I couldn't find a straightforward way to do this, my code is like this:
> 
> ////////////////////////////In Erlang//////////////////////////
> %Co_list is the list of company_info records
> 
> cal_win_notice({Co_id, Ca, Adgrp, Price, Cur}, 
>     #state{company_list = Co_list, campaign_list= Ca_list} = State) ->
>     case lists:any(fun(#company_info{company_id = A}) -> A == Co_id end, 
>             Co_list) of
>         true -> 
>             New_co_list = lists:map(fun(R) -> 
>                         case R#company_info.company_id of
>                             Co_id ->
>                                 R#company_info{consumption = R#company_info.consumption + Price};
>                             _ ->
>                                 R
>                         end
>                     end,
>                 Co_list),
>             {ok, State#state{company_list = New_co_list}};
>         false ->
>             {not_found, State} 
>     end.
> 
> Well, as shown above, the codes in bold fonts are doing the same logic which in C can be done in just one expression. This will certainly make the code unnecessarily verbose when there are more similar operations to come. What should I do? I think this is due to Erlang's feature, but in case I am wrong and making a simple thing complicated ...
> 
> I would appreciate so much with any advises.
> 
> Best regards
> Zhiqian
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions




More information about the erlang-questions mailing list