4

I've done some research on mappings and structs, and I know it's possible to store structs in a mapping as the value but not the key.

I am trying to creating a mapping of addresses => structs where multiple addresses are pointing to the same struct.

For example, I have the following test structure and mapping.

struct test{
uint nonce;
address friend;
}

mapping (address => test) testMapping;

Is it possible for me have two different addresses mapping to the same struct (not just the same data - I don't want to make a copy for efficiencies sake)?

If I were to writing the following code, would I be making a copy of the data within the struct or simply pointing two different keys to the same location in memory within the mapping?

testMapping[address1].nonce = 1;
testMapping[address1].friend = address2;
testMapping[address3] = testMapping[address1];

AKA, do the above commands copy the values from testMapping[address1] into testMapping[address2], or does it simply point testMapping[address2] to the same memory location as testMapping[address1], in which case, when I update one, both are updated?

Thanks for any help.

Nate Rush
  • 770
  • 6
  • 13

2 Answers2

4

Yes, you would be making a copy.

What you could do instead is to just have an array of tests and then map addresses to array indices.

struct test{
    uint nonce;
    address friend;
}

mapping (address => uint) testMapping; //Maps addresses to index in `tests`
test[] tests;
Tjaden Hess
  • 37,046
  • 10
  • 91
  • 118
  • Thanks for the reply. Quick follow up question. Say I were to want to add a new test on to the array. I assume I can't do tests.push(INFO) as it's a structure. How do I increase the size of such array then? Thanks again. – Nate Rush Feb 12 '17 at 05:45
2

"would I be making a copy of the data within the struct?"

Yes.

That would tend to get more expensive with the size of the struct.

It looks like you want to create table-like storage for Persons with a many-to-many association to other Persons. It's doable using mappings for random access and arrays for lists of keys. Here, a Person has a list of friends.

struct PersonStruct {
    string data1;
    uint data2;
    address[] friends;
}

mapping (address => PersonStruct) personStructs;

This is really simplistic; just to help you think about the possibilities. You would be able to enumerate the "friends" list for a given Person with a few functions to help out.

Consider a function to return the number of friends stored in the list inside a Person's struct:

function personFriendCount(address person) constant returns(uint count) {
    return personStructs[person].friends.length;
}

And another to return the friend keys as the client works its way through the list.

function personFriendAtIndex(address person, uint index) constant returns(address friendAddress) {
    return personStructs[person].friends[index];
}

With the friend's key in hand, the client can go fetch the struct for the details.

Hope it helps.

Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145