michszm
michszm

Reputation: 113

How to change value of item in stl list?

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

Answers (2)

Ely
Ely

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

coyotte508
coyotte508

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

Related Questions