Filtering a map

Hello,

I would like to return a filtered list from a map.

Here are my records:

record meme =
      { memeLordAddress : address,
        url            : string,
        name           : string,
        voteCount      : int,
      }

    record memeLord = {
        name : string,
        donation: int
    }
    record state =
      { memes      : map(int, meme),
        memeLords   : map(address, memeLord)
        memesLength : int }

Now I would like to implement a function that will return all memes from one memeLord

entrypoint getMemesForMemeLord (memeLordAddress : address):
        switch(Map.lookup(memeLordAddress, state.memeLords))
            None => abort("Meme Lord Unknown") 
            Some(x) => 

How should I filter memes to return only the memes that has the address from the request?

Also, should I return map, list or something else?

Thank you

1 Like

Hey,

Checkout the sophia standard library where you can find lots of different helpful functions.

You can use Map.to_list() and then use the filter() from the stdlib.

Tip: Instead of storing memesLength you can use Map.size() for getting the size of the map of memes when needed.

1 Like

Here is my current code

    entrypoint getMemesForMemeLord (memeLordAddress' : address) : list(meme) =
        switch(Map.lookup(memeLordAddress', state.memeLords))
            None => abort("Meme Lord Unknown") 
            Some(x) => Map.to_list(state.memes).filter((x) => x.memeLordAddress == memeLordAddress')

And I get

type_error: Not a record type: list((int * meme))
At: Line 35, column 24

List.filter((x) => x.memeLordAddress == memeLordAddress', Map.to_list(state.memes))

Thank you so much for the help so far.

Here is the code now

include "List.aes"
payable contract MemeVote =

    record meme =
        { memeLordAddress : address,
        url            : string,
        name           : string,
        voteCount      : int
        }

    record memeLord = {
        name : string,
        donation: int,
        memeLordAddress: address
        }

    record state =
        { memes      : map(int, meme),
        memeLords   : map(address, memeLord)
        }

    entrypoint init() = {
        memes = {},
        memeLords = {} 
        }

    entrypoint getMeme(index : int) : meme =
        switch(Map.lookup(index, state.memes))
            None    => abort("There was no meme with this index registered.")
            Some(x) => x

    entrypoint getMemesForMemeLord (memeLordAddress' : address) : list(int * meme) =
        switch(Map.lookup(memeLordAddress', state.memeLords))
            None => abort("Meme Lord Unknown") 
            Some(x) => List.filter((x : (int * meme) => x.meme.memeLordAddress == memeLordAddress', Map.to_list(state.memes))

And I get an error on List.filter

parse_error: Unexpected token '.'.
At: Line 35, column 58

how do you access one part of the tuple?

I never worked with funcctional programming before, and I find it hard to work without code completion :slight_smile:

I would probably write it like:
Some(x) => [ (i, m) | (i, m) <- Map.to_list(state.memes), if(m.memeLordAddress == memeLordAddress') ]

Code completion mainly helps when you know a function exists and can’t remember its name, it wont really help you learn functional programming…

1 Like

Do you mind explaining what happened there :slight_smile:
I am a quick learner.

Or at least point to a article or doc where can I learn about those operators

| , <- and all of that inside []

Thank you so much

The Sophia documentation covers this briefly. It is a list comprehension if you are interested in it in a more general sense.

wicked
thank you

1 Like