Arrays, Structs & Mappings

#1

#2

Ohh duuuuuddeeee, Iâ€™m the first comment.
I feel so powerful.

#3

Hi Filip,

In the example where you have mapping ownerToDog[owner]=id; if the same owner (address) input more than 1 dog, only the latest dog id will be retrieved. In order to retrieve all the dogs that belong to a certain owner, seems like you would need map: owner => an array of idâ€™s. Correct?

Thanks.

#4

Lets push it to the limits.

Here is a progression of the code.

This is leading up to a profile that can be used for people. (Next assignment foreshadow)

``````pragma solidity^0.4.0;

//Create a contract named DogContract
contract DogContract{
//Create a struct named Dog with a string name
//and an unassigned integer age.
struct Dog {
string name;
uint age;
string breed;
}
//Dog is it is a struct and thus can be called as an array,
//The Dog Array is named dogs.
Dog[] dogs;

// Keep Track of the owner by using a mapping structure to have key point to an
//unassigned integer for the index position in the array.

//Setter function to add a dog. The input parameters are with a string name
//and an unassigned integer age
function addDog(string _name, uint _age, string _breed){

//create owner variable of type address equat to the transactor.

// Push input for the transactor into the dogs array.
//This will return the id of the dog in the list (returns the index possition in the array)
// therefore we stroe it as an unsigned integer named id
uint id = dogs.push(Dog(_name, _age, _breed));

ownerToDog[owner]=id;
}
function getDogName() view returns (string){
uint id = ownerToDog[owner];
return dogs[id - 1].name;
}
function getDogAge() view returns (uint){
uint id = ownerToDog[owner];
return dogs[id - 1].age;
}
function getDogBreed() view returns (string){
uint id = ownerToDog[owner];
return dogs[id - 1].breed;
}
}``````

#5

Alright here is the Average Age in the group.

``````pragma solidity^0.4.0;

contract Profile{

struct Person{
string name;
uint age;
}
Person[] people;

function setPerson(string _name, uint _age){
uint id = people.push(Person(_name, _age));
ownerToProfile[owner] = id;
}
function getAvgAge() view returns (uint){
uint sumAges;
for (uint i=0; i<people.length; i++){
sumAges += people[i].age;
}
return (sumAges/people.length);
}
}
``````

Test net live on Rinkeby at the contract address

`0xbdf0f34c3cba52f714de64d5d8ede6957bdd1c7c`

https://rinkeby.etherscan.io/tx/0xf3d2b8e697a5483a7290172bbc439043d58119ebf8d1c9660008a23b1c9b4610

This will load the contract from the Test Net and allow you to submit your response. Remember when submitting setPerson you must use parenthesis for string input.

For example

``````"Guactoshi", 27
``````

would be my imput for setPerson.

#6

Question - does solidity automatically initialise all uint variables to zero if not explicitly specified?

#7

Yes, you are correct. Good point! That is a limitation that could be resolved with the mapping pointing to the array. For better behaviour you could also add a â€śrequireâ€ť check to see if the owner owns any previous dog to prevent the loss of a dog

#8

Yes, thatâ€™s right. uint will initialize to 0 and bool to false etc. They all have whatâ€™s called a zero state to begin with.

#9

I am reviewing the lecture over and over.
Iâ€™ve got the arrays and structs down. But mapping isâ€¦

I think itâ€™s the syntax.

//Update

Average age :

pragma solidity ^0.4.0;

contract AverageAge
{
struct Per
{
string name;
uint age;
}

``````Per[] people;

function setPerson(string _name, uint _age)
{
people.push(Per(_name,_age));
}

function getAve() view returns(uint)
{
uint ave = 0;
for(uint count = 0; count<people.length; count++)
{
ave = ave + people[count].age;

}

return ave/count;

}
``````

}

// June 22ndâ€¦UPDATE
Finally understand mappings and how to use them properly. It took me a few days.
I did it in parts. First understand how itâ€™s created, then how itâ€™s used in the setter, then the getter.

#10

Youâ€™re not alone I too need to rewatch it a few times.

#11

I am not sure why I am getting this error.

pragma solidity ^0.4.0;

contract Persons{

``````struct People{

string name;
uint age;

}

People[] listOfPeople;

listOfPeople.push(People(_name, _age));
}

function getAverageAge() view returns(int){

uint total = 0;

for(uint count = 0; count < listOfPeople.length; count++){
total = total + People[count].age;
}

}
``````

}

browser/Exercise2.sol:23:36: TypeError: Integer constant expected.
total = total + People[count].age;
. . . . . . . . . . . . . . . . . .^â€”^

#13

Nevermind. I needed to have â€ślistOfPeople[count].ageâ€ť instead of â€śPeople[count].ageâ€ť.

#14

IM following you on the ethereum course but when i try to deploy my dog contract i receie following error when trying to deploy following code

pragma solidity ^0.4.0;

contract DogContract{

``````string[] dogs = ["Paul", "bob", "jimmy", "rudi"];

dogs.push(_name);
}

function getDog(uint _id) returns (string){
return dogs[1];
}
``````

}

THis is the error message:
creation of DogContract pendingâ€¦
[vm]from:0xca3â€¦a733cto:DogContract.(constructor)value:0 weidata:0x608â€¦50029logs:0hash:0x7e0â€¦569fe

#15

Hi @yayo,

That is not an error message that you have posted there. It just says that the creation of the contract is pending. Is there any other message in the console? Could you maybe screenshot what it looks like when you try to create?

#17

The contract looks deployed to me. Look at the bottom left at the screen. There you will see DogContract and itâ€™s two methods.

#20

so uint can also be used as a variable!?
i thought uint only describes a â€śstateâ€ť - that it cant be negative

#21

can Someone explain me deeper this line? : msg.sender

#22

@yayo uint is a data type and it can be used like the way you use intâ€¦

E.g.

uint age = 25;

The difference is that uint holds positive numbers.

@Danny1
Remember that in JS array.length returns a number equal to the amount of elements in an array.
In the same way msg.sender returns the address of the one that called the function or contract.
So based on that I would say that when a function is called the action produces a variable and sender is one of itâ€™s properties. At least this is how I wrapped my head around it.

#23

Hi Filip,
pragma solidity^0.4.0;

contract DogContract{

``````struct Dog {
string name;
uint age;
}

Dog[] dogs;

function addDog(string _name, uint _age) internal {
uint id = dogs.push(Dog(_name, _age));
ownerToDog[owner] = id;
}

function getDog() returns (string) {
uint id = ownerToDog[owner];
return dogs[id-1].name;
}
``````

}

what does the key word â€śinternalâ€ť do exactly ?

#24

The keyword â€śinternalâ€ť changes the visibility of the function.

So, by default the contract can be seen internally as well externally. Internally means that when we do inheritance one contract can see the functions of another. That is when we use the keyword â€śisâ€ť. Example(contract Dog is dogKennel). If we set the functions in Dog to â€śinternalâ€ť they can only be accessed by dogKennel.

Externally means that it can be accessed via the getter and setter buttons for example.

So thatâ€™s why when we use â€śinternalâ€ť the button on the right disappeared and we were no longer able to interact with it from the console. The only way to access it now is through another contract(or function) internally.

On the other hand if we made Dog â€śexternalâ€ť the functions would not be available to dogKennel however we would be able to interact with it from the outside( e.g via the console on the right).

// I am aware that it may not be precisely as I explained it but thatâ€™s the gist of things.