Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unique index in C++ map with custom sorting

I have a custom key for a std::map like that:

struct Foo
{
    Foo(int _uid, int _priority) : unique_id(_uid), priority(_priority) {}

    bool operator<(const Foo& other) const {    
        return priority < other.priority;       
    }

    int unique_id;
    int priority;
};

I'm creating the map with this code:

std::map <Foo, int> bla;

And this is how I am inserting items:

bla.insert(std::pair<Foo, int> (Foo(1,2), 3) )

This works fine, and the sorting works too. But my problem is, how can I find an item only by the unique_id? The find function requires a Foo, and this requires a priority, which I don't have when I query it.

I would more like to store the priority in the value (not as the key), but I don't know how I can sort by value then. Is a std::map the right class/template for that?

Edit: I don't have the ability to use boost, also the prioritys are not unique.

like image 243
tobspr Avatar asked Oct 25 '25 00:10

tobspr


2 Answers

how can I find an item only by the unique_id?

the problem with this question is that the list contains Foo classes and ordered by priority. this makes it problematic to search for items by unique_id.

what i'm suggesting is to create a new std::map

std::map <int, foo> uniqueId_To_FooClass;

and when adding to bla a new item, add it to uniqueId_To_FooClass. that way you can find a foo class by unique_id

I would more like to store the priority in the value (not as the key), but I don't know how I can sort by value then. Is a std::map the right class/template for that?

As far as I can remember, std::map will give you the iterator that will go through the items sorted by the key. Only way to go through the sorted items by the value, and still use the map, is to rewrite whole collection to another map, with key and value reversed.

you can also look here on Oli Charlesworth answer

like image 177
No Idea For Name Avatar answered Oct 27 '25 14:10

No Idea For Name


If you're fine with linear search, then you can use std::find_if:

auto it = std::find_if(bla.begin(), bla.end(), 
                       [given_id](std::pair<Foo, int> const & p)
                        {    
                            return p.first.unique_id== given_id;
                        });

if (it != bla.end() )
       //found

Hope that helps.

like image 45
Nawaz Avatar answered Oct 27 '25 14:10

Nawaz