Print values from structure - c++

I have structure:
std::map<std::string, std::vector > someValues;
How can I print all values like:
1, string
2, values from vector?
I have more maps in my c++ project and i need some loops to printf all values.

This might work for what you want.
for (const auto& [key, vec] : someValues) {
std::cout << key << std::endl;
for (const auto& val : vec) {
std::cout << " " << val << std::endl;
}
}

Related

How to insert and iterate elements to this kind of map. C++

I tried on my own. But I was unable to do it. So, please help.
unordered_map<string, pair<string , vector<int>>> umap;
Or more precisely, how We can make pair of one string and one vector that can be used in map.
Well you can use insert function and insert them as a pair (Or precisely nested pairs).
For example Checkout this program :
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
unordered_map<string, pair<string , vector<int>>> umap;
//Insert like this
umap.insert(make_pair("first", make_pair("data1",vector<int>(3, 0))));
umap.insert(make_pair("second", make_pair("data2",vector<int>(3, 1))));
//or like this
string s = "new", t= "method";
vector <int> v = {1, 2, 3};
umap.insert(make_pair(s, make_pair(t, v)));
//This will print all elements of umap
for(auto p : umap)
{
cout << p.first << " -> " << p.second.first << " , VECTOR : " ;
for(auto x : p.second.second)
cout << x << ',';
cout << endl;
}
cout << endl;
//Let's see how to change vector already inside map
auto itr = umap.begin();
cout << "BEFORE : ";
for(auto x : (itr->second).second)
{
cout << x << ',';
}
cout << endl;
//We will push 42 here
(itr->second).second.push_back(42);
cout << "AFTER : ";
for(auto x : (itr->second).second)
{
cout << x << ',';
}
cout << endl;
}
Output Is :
new -> method , VECTOR : 1,2,3,
second -> data2 , VECTOR : 1,1,1,
first -> data1 , VECTOR : 0,0,0,
BEFORE : 1,2,3,
AFTER : 1,2,3,42,
I hope this helps.
This depends a lot on the complexity of what you are creating. For example, if you have some constants in your vector, you could make them in place:
umap.emplace("s", std::make_pair("s2", std::vector<int>{1, 2, 3, 4}));
It is more likely however that you will be making the internals in some complex way. In which case you could more easily do it as separate constructions.
std::vector<int> values;
values.push_back(1);
auto my_value = std::make_pair("s2", std::move(values));
umap.emplace("s2", std::move(my_value));
Using move to move the data around ensures minimal copying.
Finally, to iterate the items, it is normal to use range-based for loops:
for (const auto& [key, value]: umap) {
std::cout << key << ": ";
const auto& [name, values] = value;
std::cout << name << " {";
for (auto val : values) {
std::cout << val << " ";
}
std::cout << "}\n";
}
Here you can check out a live example.

How to print the content of a nested std::unordered_map?

I'm trying to print all the content of an std::unordered_map specified like this:
std::unordered_map<uint64_t, std::unordered_map<uint64_t,uint64_t>> m;
After adding things in the map, I tried the following:
for (auto it=map.begin(); it!=map.end(); it++) {
cout << it->first << it->second << endl;
}
but it is not working.
Since you have nested std::unordered_map, following should work:
for (auto const& i : m) {
for (auto const& j : i.second) {
std::cout << j.first << " " << j.second << std::endl;
}
}
You have to iterate over the nested map as well. And when you work with maps it is very convenient to use a range-based for on top of a structured binding. To avoid these cryptic first and second things:
for (const auto& [key1, value1] : map)
for (const auto& [key2, value2] : value1)
std::cout << key2 << " " << value2 << std::endl;
It works only in C++17 though. If you cannot use it, then you have the answer by NutCracker.
How to print the content of a nested std::unordered_map?
To print nested std::unordered_map use nested range-based for loop.
for (auto const& i: m) {
std::cout << "Key: " << i.first << " (";
for (auto const& j: i.second)
std::cout << j.first << " " << j.second;
std::cout << " )" << std::endl;
}
However, if you want to modify the container's elements:
for (const& i: m) {
for (const& j: i.second)
// Do operations
}

How to iterate over a map of set (std::map<std::set< char>, int >) in C++?

For a particular set as key I want to increment how many times the set occurs:
key value
ex : [a , b , c ] =3 times
[a , i ] = 2 times
and so on.
how can i iterate over it?
So far i written this ..
map<set<char> , int > mp;
for(auto const& elem : mp) {
for(set<char> :: iterator it = elem->first.begin(); it !=elem->first.end();++it)
cout << *it << ", ";
cout<<mp[elem]<<" ";
cout<<"\n";
}
but it shows error.Help!
You only have const access to the key of a map, yet you are trying to use a non-const set iterator. That can't work.
The fixed version of your code is:
for(auto const& elem : mp) {
for(set<char>::const_iterator it = elem.first.begin(); it !=elem.first.end();++it)
cout << *it << ", ";
cout<<mp[elem]<<" ";
cout<<"\n";
}
Or:
for (const auto& elem : mp) {
for (auto it = elem.first.begin(); it != elem.first.end(); ++it)
std::cout << *it << ", ";
std::cout << elem.second << '\n';
}
Or the readable alternative:
for (const auto& [key,value] : mp)
{
for (const auto& el : key)
{
std::cout << el << ", ";
}
std::cout << value << '\n';
}
I think you need something like this:
for (const auto &map_elem : mp)
{
for (const auto &set_elem : map_elem.first)
{
...
}
}
Live demo

C++: print out vector elements in a set container

I want to print out the vector element in a set container. I did the code as follows:
int main() {
vector<int> aa = {3, 2, 1, 1};
vector<int> bb = {5, 1, 7, 9};
set<vector<int>> myset; // setVector
myset.insert(aa);
myset.insert(bb);
for (auto elem : myset) {
cout << elem << ", ";
}
return 0;
}
However, this code can not print out the vector: (3, 2, 1, 1) and (5, 1, 7, 9).
you should also loop your vector elements inside myset.
for (auto const &elem : myset) { // loop set elements
for (auto const &v: elem) { // loop vector elements
std::cout << v << ", "; // print each vector element
}
std::cout << std::endl;
}
auto elem: myset here elem refers to the vectors.
to print out the contents of the vectors do this:
for (auto elem : myset)
{
for(auto x:elem) // elem is each vector
{
std::cout << x << " ";
}
std::cout << std::endl;
}
Here you iterate over the vectors in the inner for loop.
Also, you might want to use auto& in the loop if you are updating elements or to prevent copies since then you get a reference.
In order to print which you tried. You should overload << operator.
Also you may use like this.
for (auto elem : myset) {
cout << "(";
for(auto item:elem)
{
cout << item << ",";
}
cout << ")";
cout << endl;
}

C++ Loop through Map

I want to iterate through each element in the map<string, int> without knowing any of its string-int values or keys.
What I have so far:
void output(map<string, int> table)
{
map<string, int>::iterator it;
for (it = table.begin(); it != table.end(); it++)
{
//How do I access each element?
}
}
You can achieve this like following :
map<string, int>::iterator it;
for (it = symbolTable.begin(); it != symbolTable.end(); it++)
{
std::cout << it->first // string (key)
<< ':'
<< it->second // string's value
<< std::endl;
}
With C++11 ( and onwards ),
for (auto const& x : symbolTable)
{
std::cout << x.first // string (key)
<< ':'
<< x.second // string's value
<< std::endl;
}
With C++17 ( and onwards ),
for (auto const& [key, val] : symbolTable)
{
std::cout << key // string (key)
<< ':'
<< val // string's value
<< std::endl;
}
Try the following
for ( const auto &p : table )
{
std::cout << p.first << '\t' << p.second << std::endl;
}
The same can be written using an ordinary for loop
for ( auto it = table.begin(); it != table.end(); ++it )
{
std::cout << it->first << '\t' << it->second << std::endl;
}
Take into account that value_type for std::map is defined the following way
typedef pair<const Key, T> value_type
Thus in my example p is a const reference to the value_type where Key is std::string and T is int
Also it would be better if the function would be declared as
void output( const map<string, int> &table );
The value_type of a map is a pair containing the key and value as it's first and second member, respectively.
map<string, int>::iterator it;
for (it = symbolTable.begin(); it != symbolTable.end(); it++)
{
std::cout << it->first << ' ' << it->second << '\n';
}
Or with C++11, using range-based for:
for (auto const& p : symbolTable)
{
std::cout << p.first << ' ' << p.second << '\n';
}
As #Vlad from Moscow says,
Take into account that value_type for std::map is defined the following way:
typedef pair<const Key, T> value_type
This then means that if you wish to replace the keyword auto with a more explicit type specifier, then you could this;
for ( const pair<const string, int> &p : table ) {
std::cout << p.first << '\t' << p.second << std::endl;
}
Just for understanding what auto will translate to in this case.
As P0W has provided complete syntax for each C++ version, I would like to add couple of more points by looking at your code
Always take const & as argument as to avoid extra copies of the same object.
use unordered_map as its always faster to use. See this discussion
here is a sample code:
#include <iostream>
#include <unordered_map>
using namespace std;
void output(const auto& table)
{
for (auto const & [k, v] : table)
{
std::cout << "Key: " << k << " Value: " << v << std::endl;
}
}
int main() {
std::unordered_map<string, int> mydata = {
{"one", 1},
{"two", 2},
{"three", 3}
};
output(mydata);
return 0;
}
if you just want to iterate over the content without changing values
do:
for(const auto & variable_name : container_name(//here it is map name)){
cout << variable_name.first << " : " << variable_name.second << endl;
}
If you want to modify the contents of the map, remove the const and keep & (if you want to modify directly the contents inside container). If you want to work with a copy of the container values, remove the & sign too; after that, you can access them by using .first and .second on "variable_name".
it can even be done with a classic for loop.
advancing the iterator manually.
typedef std::map<int, int> Map;
Map mymap;
mymap['a']=50;
mymap['b']=100;
mymap['c']=150;
mymap['d']=200;
bool itexist = false;
int sizeMap = static_cast<int>(mymap.size());
auto it = mymap.begin();
for(int i = 0; i < sizeMap; i++){
std::cout << "Key: " << it->first << " Value: " << it->second << std::endl;
it++;
}
Other way :
map <int, string> myMap = {
{ 1,"Hello" },
{ 2,"stackOverflow" }
};
for (auto iter = cbegin(myMap); iter != cend(myMap); ++iter) {
cout << iter->second << endl;
}