stl::multimap - how do i get groups of data?
pair<Iter, Iter> range = my_multimap.equal_range("Group1");
int total = accumulate(range.first, range.second, 0);
Is one way.
Edit:
If you don't know the group you are looking for, and are just going through each group, getting the next group's range can be done like so:
template <typename Pair>
struct Less : public std::binary_function<Pair, Pair, bool>
{
bool operator()(const Pair &x, const Pair &y) const
{
return x.first < y.first;
}
};
Iter first = mmap.begin();
Iter last = adjacent_find(first, mmap.end(), Less<MultimapType::value_type>());
C++: Storing groups of three in a multimap
Yes. Using std::pair is a reasonable way to represent the values {b,c} and {e,f}
You would store each one in the multimap with key a, value {b,c} and key D, value {e,f}.
Then later you might have key a, value {z,y}. When that is inserted, you can then find key a, and it will return a iterator that you can fetch all of the values associated with key a.
If you do have tuples, then you might consider using key a, with the tuple {a,b,c}.
How to create table of grouped multimap key and associated values in c++
From your question it appears you want to store the records in the format (key,value). For this you can encapsulate the non-key columns in an object and store it in a multimap like (key, object*).
I have modified your code for the same as given below-
class DATA
{
public:
//control access to data members as needed
string name;
string type;
string value;
DATA(string name, string type, string value): name(name), type(type), value(value) {}
};
typedef multimap<string, DATA*> StringToIntMap;
typedef StringToIntMap::iterator mapIter;
int main ()
{
StringToIntMap mymap;
//insert record {"group1","pointcloud_min_z", "int_t","24"}
DATA *elem = new DATA("pointcloud_min_z", "int_t","24");
mymap.insert(make_pair("Group1", elem));
//insert record {"group1","pointcloud_max_z", "bool_t","true"}
elem = new DATA("pointcloud_max_z", "bool_t","true");
mymap.insert(make_pair("Group1", elem));
//insert record {"group2","pointcloud_max_z", "double_t","13"}
elem = new DATA("pointcloud_max_z", "double_t","13");
mymap.insert(make_pair("Group2", elem));
//insert record {"group2","pointcloud_min_z", "double_t","20.0"}
elem = new DATA("pointcloud_min_z", "double_t","20.0");
mymap.insert(make_pair("Group2", elem));
cout << "mymap contains:" << endl;
mapIter m_it, s_it;
for (m_it = mymap.begin(); m_it != mymap.end(); m_it = s_it)
{
string theKey = (*m_it).first;
cout << endl;
cout << " key = '" << theKey << "'" << endl;
pair<mapIter, mapIter> keyRange = mymap.equal_range(theKey);
// Iterate over all map elements with key == theKey
for (s_it = keyRange.first; s_it != keyRange.second; ++s_it)
{
cout << " value = " << (*s_it).second->name << ", "
<< (*s_it).second->type << ", "
<< (*s_it).second->value << endl;
}
}
//when done delete the record pointers from the multimap
return 0;
} // end main
Grouping by function value into Multimap
Using fromListWith
from Data.Map
:
> let xs = ["abc","abd","aab","123"]
> let f = take 2
> Data.Map.fromListWith (++) [(f x, [x]) | x <- xs]
fromList [("12",["123"]),("aa",["aab"]),("ab",["abd","abc"])]
how to link data in multiple multimaps together (C++)?
If your multimap is sorted by symbol and then price, you can use multimap::lower_bound
and multimap::upper_bound
to iterate over the range of elements with a specified symbol. When searching in the map sorted from lowest price to highest, set the price to INT_MIN
when you call lower_bound
and INT_MAX
when you call upper_bound
.
Also, in general, how do you modify values in multimaps
To modify the value you can just assign to it. To modify the key you have to remove it and insert a new one.
Find function in STL C++ for unordered multimap?
You could use equal_range
, which returns a pair of iterators to the range of elements matching a key.
Summing together same-key items from a multimap?
There are four problems with this code:
- You have too many closing angle brackets.
- Your multimap probably shouldn't be named
multimap
. (Although this might not cause a compile error, it's pretty obvious that you shouldn't do it.) - Dereferencing a multimap iterator gives a key-value pair, rather than just the value. So of course you can't sum these with
std::accumulate
directly. - Even if you did this with a multiset instead of a multimap, so #3 wouldn't apply, passing
0
as the initial value will cause all the floats to be truncated as it would deduce typeint
for the accumulator... so you would probably get the wrong answer.
It looks like you're stuck in 2003, since you actually wrote out the return type of equal_range
, so I guess no lambdas or range-for-loops for you.
pair<multimap<int32_t, float>::iterator,
multimap<int32_t, float>::iterator> range = M.equal_range(an_int);
float total = 0;
for (multimap<int32_t, float>::iterator I = range.first; I != range.second; ++I) {
total += I->second;
}
Or avoid equal_range
and that nasty declaration altogether...
float total = 0;
for (multimap<int32_t, float>::iterator I = M.lower_bound(an_int);
I != M.end() && I->first == an_int;
++I) {
total += I->second;
}
Edit: Okay, so you do have C++11 support. So you can do this:
auto range = M.equal_range(an_int);
float total = accumulate(range.first, range.second, 0.0,
[](float x, pair<int32_t, float> y) { return x + y.second; });
(Note: If you have C++14 support, you can even replace pair<int32_t, float>
by auto
in the lambda.)
Multimap containing pairs?
Is it possible for a multimap to contain within it pairs?
Yes its possible.
How would this multimap then be sorted?
By the key/first pair (ie, first by the first element of the first pair, then by the second element of the first pair).
Also, how would one access the individual contents of each pair?
multimap<pair <T1, T2>, pair<T3, T4> >::iterator it = mymultimap.begin();
it->first.first;
it->first.second;
it->second.first;
it->second.second;
In other words, a multimap of pairs works exactly as expected!
Update:
Also, I'd like to add that I discourage any use of pairs of pairs, it makes the code very hard to read, use structs with real variable names instead.
Related Topics
Why Does Long Long N = 2000*2000*2000*2000; Overflow
Returning a Pointer of a Local Variable C++
Check If a String Is Palindrome
Destroy and Then Construct New Object Using the Same Variable
Using Namespace Std; in a Header File
Undefined Reference to Vtable. Trying to Compile a Qt Project
Why Can't the Compiler Deduce the Template Type from Default Arguments
Why Are My Struct's Members Not Properly Initialised Using '{}'
C++ Handling Very Large Integers
How to Enable _Int128 on Visual Studio
Floating Point Equality and Tolerances
Reading from Ifstream Won't Read Whitespace
How to Write Custom Input Stream in C++
Is There a Compiler Hint for Gcc to Force Branch Prediction to Always Go a Certain Way
Extract Year/Month/Day etc. from Std::Chrono::Time_Point in C++