-2

I have map<int, vector > like this:

#include <iostream>
#include <map>
#include <vector>

using namespace std;

int main() {
    
    map<int, vector <int>> someMap;
    someMap[5] = {5, 2, 3, 7};
    someMap[151] = {5, 9, 20};

    return 0;
}

I need to find the last vector element in each map value. Output must be like this:

7
20

Thanks :)

maxet24
  • 111
  • 1
  • 10
  • Also related: [c++ vector last element field](https://stackoverflow.com/q/14275291/4284627) – Donald Duck Nov 21 '21 at 11:52
  • Like most containers, std::map has a reverse_iterator. The documentatjon is at cppreference dot com. map::rbegin( ) would be a good place to start looking. – Michaël Roy Nov 21 '21 at 11:53
  • `for (auto& vector : someMap) { ... }`. The fact that you havn't put in the effort the look up even the basic functionality of a the standard containers, or at least neglectged to show that attempt in your question makes your question in danger of getting closed. Please read [ask] and how to make a [mcve]. Show what you've tried and what didn't work with yout attempt. – super Nov 21 '21 at 11:56
  • @super It should be `for (auto& [integer, vector] : someMap) { ... }`. If you just do `for (auto& vector : someMap)`, `vector` won't contain the vector but a `std::pair>`. – Donald Duck Nov 21 '21 at 11:58

2 Answers2

3

You've got to love the C++17 structured bindings:

std::map<int, std::vector<int>> m = {
    {5, {5, 2, 3, 7}},
    {151, {5, 9, 20}},
};

for (const auto& [_, v] : m)
{
    if (!v.empty())
    {
        int last = v.back();
    }
}

Some other resources:

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
bolov
  • 72,283
  • 15
  • 145
  • 224
1

You can use the std::vector::back member function as shown below:

#include <iostream>
#include <map>
#include <vector>
#include <cassert>
using namespace std;

int main() {
    
    map<int, vector <int>> someMap;
    someMap[5] = {5, 2, 3, 7};
    someMap[151] = {5, 9, 20};
    //iterate through each element of the map
    for(const std::pair<int, std::vector<int>> &myPair: someMap)
    {
        //make sure the vector is not empty
        assert(!myPair.second.empty());
        
        //print the last element in the vector
        std::cout << myPair.second.back() <<std::endl;
    }
    return 0;
}

The output of the above program is:

7
20

which can be seen here.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • 2
    The `for`-loop looks like back in 2011. It would be better to use [structured binding](https://en.cppreference.com/w/cpp/language/structured_binding). This situation is a textbook use case for structured binding. – Andrej Podzimek Nov 21 '21 at 12:10
  • 1
    This is not bad code. It is 100% equivalent in terms of semantics and performance with the structured bindings one. C++17 is relatively new and a lot of production code is old and still using C++11 so this answer definitely still has value in 2021. I personally really like the structured bindings one, I find it more readable and easier to parse by humans. I recommend it, but that doesn't mean I think the C++11 is bad in absolute terms. Also the point of being explicit is really a valid one, though I personally try and find a balance between explicitly and brevity. – bolov Nov 21 '21 at 16:01
  • @AnoopRana This _is_ bad code, due to maintainability issues. Assume you want to change `someMap` to a `map>`. What if you forget to edit the loop? With `-Wrange-loop-construct`, you _may_ spot the bug before disaster strikes. But what if you don’t? Then shockingly enough, this will compile: `map> m{{7, {1}}}; for (const pair> &x : m) cout << x.first << ' ' << x.second.back() << '\n';` Without `-Wrange-loop-construct` you get **no warnings**. Good luck debugging why keys are clobbered. `auto` and structured binding avoid such problems. – Andrej Podzimek Nov 21 '21 at 22:55
  • Actually, using e.g. `999999999999ll` as a key (above) instead of `7` would make the problem even more obvious. The output is `-727379969 1` in that case (unless it is UB, at which point it can be whatever). Forgetting to edit the loop is a mistake easy to make, especially when the data type definition and the loop are in different files, on different “sides of the API” etc. Structured binding saves lots of tedious and error-prone loop editing and prevents many of these errors from happening in the first place. – Andrej Podzimek Nov 21 '21 at 23:08