Nicholas Drake
Nicholas Drake

Reputation: 149

In erlang how do I unpack a list of tuple in a function argument?

I have the requirement

add_items(AuctionId, [{Item, Desc, Bid}]) -> {ok, [{ItemId, Item]} | {error, unknown_auction}.

How do I use the list of tuples to write my function body?

What I've tried:

add_items(AuctionId, ItemList) -> ...

This works fine, but I haven't matched the requirement - but the requirement returns a function_clause error if I define it that way as it cannot be pattern-matched (and I don't think the question wants me to define the specification this way either as I would write something like

-spec add_items(reference(), [item_info()]) -> 
{ok, [{itemid(), nonempty_string()}]} | {error, unknown_auction()}.

It also does not match say trying to do a recursion definition with a head and a tail ala [] and [H|T]

Upvotes: 0

Views: 547

Answers (1)

7stud
7stud

Reputation: 48599

Here's an example of what you can do:

-module(a).
-compile(export_all).

%%add_items(AuctionId, [{Item, Desc, Bid}]) -> 
                     {ok, [{ItemId, Item]} | {error, unknown_auction}.

add_items(AuctionId, Items) ->
    case valid_auction(AuctionId) of
        true -> insert_items(Items, _Results=[]);
        false -> {error, unknown_auction}
    end.

%% Here you should check the db to see if the AuctionId exists:
valid_auction(AuctionId) ->
    ValidAuctionIds = sets:from_list([1, 2, 3]),
    sets:is_element(AuctionId, ValidAuctionIds).

%% Here's a recursive function that pattern matches the tuples in the list:
insert_items([ {Item, Desc, Bid} | Items], Acc) ->
    %%Insert Item in the db here:
    io:format("~w, ~w, ~w~n", [Item, Desc, Bid]),
    ItemId = from_db,
    insert_items(Items, [{ItemId, Item} | Acc]);
insert_items([], Acc) ->
    lists:reverse(Acc).

In the shell:

8> c(a).                                
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

9> a:add_items(4, [{apple, fruit, 10}]).
{error,unknown_auction}

10> a:add_items(1, [{apple, fruit, 10}, {cards, game, 1}]).
apple, fruit, 10
cards, game, 1
[{from_db,apple},{from_db,cards}]

11> 

The shell interaction demonstrates that add_items() satisfies your requirement:

  1. It takes two arguments, with the second argument being a list whose elements are three element tuples.

  2. The return value is either an ok tuple containing a list of two element tuples; or the tuple {error,unknown_auction}.

Upvotes: 1

Related Questions