Hello,
I want to use an Array in Sophia programming language, but I realized that Sophia uses list instead. So my question is how do I add an item to the list… here is my code, I don’t know what I’m doing wrong
record state =
{ owner : address,
currentPositionId : int,
positionIdsByAddress: map(address, list(int))}
stateful entrypoint init() : state =
{ owner = Call.caller, currentPositionId = 0, positionIdsByAddress = {} }
payable stateful entrypoint depositAE(numDays: int) =
let newPositionIdsByAddress = state.positionIdsByAddress[Call.caller] ++ [state.currentPositionId]
put(state{positionIdsByAddress[Call.caller] = newPositionIdsByAddress })
I just want to add an item to the positionIdsByAddress
map whenever depositAE function is called. this is my first time coding in Sophia programming language.
Hello @paschal533,
As I understand from your code, you are trying to update the map positionIdsByAddress
but it’s not working for you.
You are trying to create a new map newPositionIdsByAddress
and then assigning it to the positionIdsByAddress
map in the state, which is fine, but there are a couple of issues to note in your code.
1. The way the new map (i.e. newPositionIdsByAddress
) is created
By doing state.positionIdsByAddress[Call.caller]
, you are trying to access the element of the map with the key Call.caller
and you are getting an error. In Sophia, no default value is assigned to a key that does not exist in the map, so you will get the error FATE error: Maps: Key does not exist
by doing that.
To fix that, we have a special syntax for assigning values to key that you are not sure if it exist: m{ [key = defaultValue] @ oldValue = newValue }
, you can read more about this in the docs Features - æternity Sophia Language.
In your case, it will become like this:
let newPositionIdsByAddress = state.positionIdsByAddress{[Call.caller = []] @ positions = positions ++ [state.currentPositionId]}
- The
[]
is the default value which is assigned to the key in case it does not exist yet in the map.
-
positions
is the old value of the key Call.caller
(if there is no old value, it will just be the default value).
-
positions ++ [state.currentPositionId]
will be the new values (appending state.currentPositionId
to the existing list).
2. When placing the newPositionIdsByAddress
in the state
The right way to do this is
put(state{positionIdsByAddress = newPositionIdsByAddress })
Because you need to assign the new map to positionIdsByAddress
which is the map in the state record, and you do not need to assign it to positionIdsByAddress[Call.caller]
which is a list (because you’re accessing an element of that map).
I hope this was helpful, please do not hesitate to ask more questions if anything was not clear enough.
4 Likes
To quickly add a single item to a list use the ::
operator. ++
is used to conatenate lists and is quite slow (linear time to the length of the left-side list).
4 Likes