Solidity Struct – How to Search by Name in Mapping

soliditystruct

In this example, how would I write a function for

getPersonByName(string _name) returns (_address) {}

// Code Example
pragma solidity ^0.4.13;

contract Project
{
    struct Person {
        string name;
        uint funds;
    }

    // this is the mapping for which we want the
    // compiler to automatically generate a getter.
    mapping(address => Person) public people;

    // this is what the automatically generated getter
    // looks like (we don't need to implement this ourselves).
    function getPerson(address id)
        public
        returns (string name, uint funds)
    {
        // copy the data into memory
        Person memory p = people[id];

        // break the struct's members out into a tuple
        // in the same order that they appear in the struct
        return (p.name, p.funds);
    }
}

Best Answer

AFAIK, this is not possible to implement in your current contract. But if you need this, you have to tweak your smart contract.

When you declare a mapping, it's a key-value pair but you can not get key from value. Ideally what you want is getting key from value and value from key. This is what we call bidirectional map. Even conventional programming languages like Java does not support bidirectional-map.

Now coming to solution part, you may declare another mapping with

mapping(string=> address) getAddressFromName;

This is the best I could think of as of now. Even if you were able to loop through mapping (which is not the case), I would have recommended this solution as lopping may create issues when data in mapping increases.

Edit:

When you add a user, you push the name and address of the sender to getAddressFromName mapping. For eg,

function addPerson (string _name, uint _funds) public {
   Person memory newPerson = Person(_name, _funds);
   people[msg.sender] = newPerson;
   getAddressFromName[_name] = msg.sender;
}

function getPersonByName(string _name) public view returns(address){
    return getAddressFromName[_name];
}

Also, note that key to mapping is unique, so when you try to add a new value with the same key, it doesn't add a new key it replaces the previous value corresponding to that key.

Related Topic