简体   繁体   中英

Erlang how to check if all elements in a list of tuples exists in another list of tuples

Say i have two lists: AmountOfProducts which has a list of tuples like

[{apple, 10}, {chocolate, 13}, {lettuce, 9}, {mango, 20}]

And the second list is the OrderProducts which has tuples like

[{apple, 3}, {chocolate, 1}, {mango 4}]

The first element is the atom for the name of the product, the second element is the amount, for AmountOfProducts the amount is the number available and for OrderProducts its the amount its asking for. Is there a way to check if the all atoms of OrderProducts exists inside AmountOfProducts and return a true? And if, lets say OrderProducts had an extra tuple and its atom didnt exist inside AmountOfProducts for it to return false? The idea is something like this:

AmountOfProducts = [{apple, 10}, {chocolate, 13}, {lettuce, 9}, {mango, 20}]
OrderProducts = [{apple, 3}, {chocolate, 1}, {mango 4}]

check_products(AmountOfProducts, OrderProducts) ->
    if
        all atoms inside OrderProducts exists in AmountOfProducts -> true;
        one or many of the atoms inside OrderProducts doesnt exist in AmountOfProducts -> false
    end.

In the given case of the two lists it should come back as true. Is there a way to do this? I hope this makes sense, Thanks!

I'll show you several ways to solve this problem.

First Version: List Comprehensions

check_products(AmountOfProducts, OrderProducts) ->
  [] ==
    [Key || {Key, _} <- OrderProducts
          , not lists:keymember(Key, 1, AmountOfProducts)].

Here we basically collect all the keys in OrderProducts that don't have a corresponding tuple in AmountOfProducts and, if that's an empty list… we return true

Second Version: High-Order Functions

check_products(AmountOfProducts, OrderProducts) ->
  lists:all(
    fun({Key, _}) ->
      lists:keymember(Key, 1, AmountOfProducts)
    end, OrderProducts).

Here we basically write what you wrote in your question, but in Erlang code: Return true if the keys of all the elements in OrderProduct are also keys in AmountOfProducts .

Third Version: Just compare the Keys

Now, if you know that there will be no duplication of keys in any of the lists, you can also write your code like this…

check_products(AmountOfProducts, OrderProducts) ->
  [] == keys(OrderProducts) -- keys(AmountOfProducts).

Basically saying that if we remove all the keys from AmountOfProducts from the list of keys of OrderProducts ... we end up with no keys (they were all removed because they belonged to AmountOfProducts ). You have to implement an auxiliary function keys/1 , but that one is hopefully much easier to implement (or you can just use proplists:get_keys/1 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM