I have created a function that receive some values from users an store them in a mapping. How to arrange the stored values in mapping according to a certain value ( Priority as in the shown example below)?

 pragma solidity ^0.4.24; 

  contract Test {

// storage is packed based on how much data we actually want to store,
// to minimise the storage costs, we're going to use expected uint types
struct StudentType {
    uint8 bonus;        // 0 - 255
    uint16 value1;      // 0 - 65535
    uint16 value2;      // 0 - 65535
    uint16 Priority;    // 0 - 65535
}

mapping (address => StudentType) public studentsByAddress; 
mapping (uint256 => address) public studentsByInsertId; 
uint256 public studentCount = 0;

function saveNewRecord(address _address, uint8 _bonus, uint16 _value1, uint16 _value2) public {          

    // instance of struct student and map it to students mapping;
    StudentType storage student = studentsByAddress[_address]; 
    student.bonus = _bonus;
    student.value1 = _value1;
    student.value2 = _value2;

    student.Priority = this.calculatePriority( _value1, _value2, _bonus);

    // map address to current insert id
    // ++uint makes our index start at 1 since the incrementation happens before 
    // if you want it to start at 0, then do uint++
    studentsByInsertId[studentCount++] = _address;

}

/*

    depending on the precision you actually want the more "zeroes" you're going to use. 
*/

function calculatePriority(uint16 _value1, uint16 _value2, uint8 _bonus) pure public returns ( uint16 ) {
    // store the calculation in a big enough value
    uint256 result = ( ( ( 50 * _value1 ) + ( 50 * _value2 ) ) / _bonus ) / 100;

    // convert result
    return uint16( result );
}

/*
    not really needed since you can use the "studentsByAddress" mapping method created by solidity
    unless you want to "hide" or manipulate some data
*/
function get_ESU(address ins) view public returns (uint, uint, uint) {
    return (
        studentsByAddress[ins].value1,
        studentsByAddress[ins].value2,
        studentsByAddress[ins].Priority
    );
}

 }

If your smart contract doesn't depend on the sorting, I would suggest to do the sorting off-chain. Every time you insert a new student, you can emit an event. Off-chain, in your application, you can fetch all the events and sort the list by priority. If you need the sorting on-chain in your smart contract code, you'll have to implement a sorting algorithm in your contract.

EDIT See Sorting an Array of integer with Ethereum for inspiration.

  • actually, it depends on the sorting. Any idea of how to implement such a sorting algorithm for my case – Mohamed Oct 4 at 21:25
  • It depends on which sorting algorithm you wish to use. You could use arrays and then write for example merge sort on this array to sort the elements by priority. See ethereum.stackexchange.com/questions/1517/… for inspiration. – ivicaa Oct 4 at 21:41
  • @ I read the link but I am not able to apply the quick sort to my case. Assume we have an array that stores all the incoming addresses. How can I sort these addresses based on its each student priority value – Mohamed Oct 5 at 1:57

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.