Reputation: 113
I have a question about changing or replacing elements in a list. I have a class:
class Node{
public:
elType type; // enum
string name;
Node(elType type, string name);
~Node();
void printNodeInfo();
}
and a list:
std::list <Node * > someList;
Now how can i replace a value (for eaxmple change type) in such element. I've tried this:
std::list<Node * >::iterator it = someList.end();
it--;
while(openName.compare((*it)->name) != 0)
it--;
(*it)->type = otherType;
But it does not seem to work, the type stays the same. I'd be grateful for any help.
EDIT: I updated the list so now I have:
std::list <Node> someList;
and changed the replacing to:
it->type = otherType;
I also tried:
std::list<Node >::iterator it2 = someList.erase(it);
Node temp(otherType, openName);
someList.insert(it2, temp);
after this for both cases a simple method for printing :
it2->printNodeInfo();
outputs nothing.
Upvotes: 1
Views: 20941
Reputation: 11152
I wonder why you use Node *
instead of Node
. Consider using list<Node>
instead of list<Node *>
unless you can give a reason why not.
I assume a list<Node>
for now.
To find an element use find from the STL. You can use it like that find(someList.begin(), someList.end(), value)
; value would be of type elType
in your case.
You also have to provide a comparison operator that compares a node's name to a give name.
Not having enough information I made a simplified example of yours. Maybe that gets you corrected/closer to what you want to achieve.
// Example program
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
enum elType { red, green, blue };
using namespace std;
class Node{
public:
elType type; // enum
string name;
Node(elType type, string name);
};
Node::Node(elType type, string name) {
this->type = type;
this->name = name;
};
// ensure that name can be found using find of STL
bool operator==(Node &n, string name) {
return n.name == name;
}
int main() {
// Create nodes
Node n1(elType::red, "Node 1");
Node n2(elType::green, "Node 2");
Node n3(elType::blue, "Node 3");
// Output node names and types
cout << n1.name << " : " << n1.type << endl;
cout << n2.name << " : " << n2.type << endl;
cout << n3.name << " : " << n3.type << endl;
// Create list of nodes
list<Node> someList{ n1, n2, n3 };
// find node with name "Node 3"
auto it = find(someList.begin(), someList.end(), "Node 3");
// if a node was found change its type to red
if ( it != someList.end() ) {
it->type = elType::red;
}
// output nodes in list
cout << endl;
for ( auto node: someList ) {
cout << node.name << " : " << node.type << endl;
}
return 0;
}
You can, as mentioned by other users, also use the reverse iterator.
In that case simple replace begin()
and end()
by rbegin()
and rend()
like so:
// find node with type "blue" and change type to "red"
auto it = find(someList.begin(), someList.end(), "Node 3");
// if a node was found change its type
if ( it != someList.end() ) {
it->type = elType::red;
}
Upvotes: 0
Reputation: 9705
I don't know what is your problem exactly, but here is your solution:
#include <iostream>
#include <string>
#include <list>
using namespace std;
class Node{
public:
int type; // enum
string name;
Node(int type, string name) : type(type), name(name) {}
~Node(){}
void printNodeInfo() const {cout << type << ", " << name << endl;}
};
void replace(list<Node> &l, const string &nameSearch, int typeReplace) {
for (auto it = l.rbegin(); it != l.rend(); it++) {
if (it->name == nameSearch) {
it->type = typeReplace;
/* To stop searching */
return;
}
}
/* Nothing replaced, error message? */
}
int main() {
list<Node> l;
l.push_back(Node(0, "World"));
l.push_back(Node(1,"Hello"));
l.push_back(Node(2,"World"));
replace(l, "World", 42);
for (const auto &el: l) {
el.printNodeInfo();
}
return 0;
}
Upvotes: 1