Reputation: 4414
If I have a set of unique vectors, how can I (for example) delete the second element in each vector? I have created the following simple example:
#include <iostream>
#include <vector>
#include <set>
#include <string>
using namespace std;
int main()
{
vector<int> myVec1 = {0, 1, 2, 3, 4, 5};
vector<int> myVec2 = {3, 5, 7, 2, 4, 1};
vector<int> myVec3 = {2, 5, 3, 8, 6, 9};
set<vector<int>> mySet;
mySet.insert(myVec1);
mySet.insert(myVec2);
mySet.insert(myVec3);
// right now this for loop deletes an element from a copy only
for(auto item : mySet) item.erase(item.begin() + 2);
for(auto item : mySet)
{
for(auto element : item) cout << " " << element;
cout << "\n";
}
}
This example can be compiled and run on cpp.sh.
Possible solutions I have considered:
for(auto& item : mySet)
; however, this gives an error on compilation (no matching member function for call in const vector)Upvotes: 0
Views: 1343
Reputation: 490683
I would use std::transform
to take the data from the existing set, modify as needed, and insert the results into a new set, then swap the old set with the new one:
std::set<std::vector<int> > mySet {
{0, 1, 2, 3, 4, 5},
{3, 5, 7, 2, 4, 1},
{2, 5, 3, 8, 6, 9}
};
std::set<std::vector<int>> temp;
std::transform(mySet.begin(), mySet.end(),
std::inserter(temp, temp.end()),
[](std::vector<int> s) { s.erase(s.begin() + 1); return s; }
);
std::swap(temp, mySet);
If you're dealing with a lot of data, you might be better off getting a vector from the input set, erasing it from the input set, erasing the element from that vector, and inserting the result into the output.
Upvotes: 1
Reputation:
You would need to remove the vector from the set of vectors before manipulating it and after the manipulation reinsert the vector.
Since this would involve a lot of creating/copying vectors, you could use pointers to vectors -- in which case you would need your own compare function object:
struct compare
{ bool operator()(
const std::shared_ptr<std::vector<int> > &_r0,
const std::shared_ptr<std::vector<int> > &_r1) const
{ return *_r0 < *_r1;
}
};
std::set<std::shared_ptr<std::vector<int> >, compare> sSet;
in order to delete the second element in each vector, I would first create a copy of all pointers:
std::vector<std::shared_ptr<std::vector<int> > > sCopy(
sSet.begin(),
sSet.end());
sSet.clear();
for (auto p = sCopy.begin(), pEnd = sCopy.end();
p != pEnd;
++p)
{ auto rVectorPtr = *p;
if (rVectorPtr->size() > 1)
rVectorPtr->erase(rVectorPtr->begin() + 1);
sSet.insert(rVectorPtr);
}
Upvotes: 0
Reputation: 4297
Probably not the solution you're looking for, but you could have your set hold pointers to vectors instead. This works for me:
int main() {
vector<int> myVec1 = {0, 1, 2, 3, 4, 5};
vector<int> myVec2 = {3, 5, 7, 2, 4, 1};
vector<int> myVec3 = {2, 5, 3, 8, 6, 9};
set<vector<int>*> mySet;
mySet.insert(&myVec1);
mySet.insert(&myVec2);
mySet.insert(&myVec3);
for(vector<int>* item : mySet) item->erase(item->begin() + 2);
for(vector<int>* item : mySet)
{
for(auto element : *item) cout << " " << element;
cout << "\n";
}
return 0;
}
Upvotes: 0