简体   繁体   中英

Sorting data using std::map or std::multimap

Happy New Year. Hope everyone is ok. I have not been here for a while.

I have some contact lens data I'm trying to sort. I have some sort rules are static (hard-coded) followed by other rules form 'normal' rules

Here are the requirements:

  1. First sort by Company and Product is a static order (hard-coded, non alphbetic)

    Sample

    o Company ProductName

    1. Ciba 1. Focus, 2. AirOptics, 3. Dailies, 4. then alphabetical.
    2. Bausch & Lomb 1. PureVision, 2. LiquidEye, 3. Softlens then alphabetical.
  2. Followed by Package size decending (80, 30 ...)

  3. Followed by Base Curve decending (8.6, 8,0 ...)

  4. Followed by Sphere decending (-0.5, 0.0, 1.0 ...)

In the end the result might look like the following

Sample data
CO    PR     PS    BC    Sp
-------------------------------
Ciba  Focus  10    8.6    0.00
Ciba  Focus  20    8.6   -0.25
Ciba  Focus  20    8.6   -0.10
Ciba  Focus  20    8.6   +0.25
Ciba  Air    10    8.6   -0.25
Ciba  Air    10    8.6   -0.10
Ciba  Air    20    8.1   -0.25
Ciba  Air    20    8.1   -0.10
Ciba  Air    20    8.1    0.00
Ciba  Air    20    8.6   +0.25
Ciba  Air    20    8.6   +0.40

The data is contained in a struct with other data. The stuct is used in a map with a key. I am building a key to sort for the static requirments such as below.

The key contains a prefix at the front of the key to force the static sort (non alphabetical), followed by a suffix to make the key unique. Sample key: "1_1_Ciba_Focus Monthlys_4"

My plan to sort the other requirments is to take each of the other requirments (PackageSize, Base Curve and Sphere) and sort them against the previous element with the key.

Since I will be sorting the following agaist the Package Size (10, 20 ...) - maybe I should be using the multimap, as it might be easter to sort this stuff without having the unique ID at the end of key ??

With the key of "1_1_Ciba Focus" I would sort on the PackSize and then set the key to produce the correct sort

start: (std::multimap)
key: 1_1_Ciba  Focus"
Sample data
CO    PR     Key
-------------------------------
Ciba  Focus  1_1_Ciba  Focus
Ciba  Focus  1_1_Ciba  Focus
Ciba  Focus  1_1_Ciba  Focus
Ciba  Focus  1_1_Ciba  Focus

Sample data
CO    PR     PS    Key
-------------------------------
Ciba  Focus  10    1_1_1_Ciba  Focus
Ciba  Focus  20    1_1_2_Ciba  Focus
Ciba  Focus  20    1_1_2_Ciba  Focus
Ciba  Focus  20    1_1_2_Ciba  Focus

Thanks, Chris chris@macgowan.com

You can write a comparison functor that can take into account any number of criteria. The idea is to start at the most significant criterion, then go down the list only when the upper levels are equal.

struct LensCompare
{
    bool operator()(const Data & left, const Data & right)
    {
        if (left.key < right.key)
            return true;
        else if (right.key < left.key)
            return false;
        if (left.PR < right.PR)
            return false;  // for descending order return "false" when less than
        else if (right.PR < left.PR)
            return true;
        if (left.BC < right.BC)
            return false;
        else if (right.BC < left.BC)
            return true;
        return right.Sp < left.Sp;
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM