Reputation: 413
I have a class of objects and need to compare one property of each object to the same property of all other objects. If they match, the code needs to do something. This results in two 'for loops' looping through the objects to get that property, and in the second 'for loop', there is a third 'for loop' going through the elements of the property (which is a vector) to compare them. If they match, I need the outer most 'for loop' to abort the current iteration and go on to the next one (I only want the first match with another object to be considered).
I have looked into 'goto' statements and into creating a do{}while() structure, but have not been able to implement them in a way to get the desired result. What I need is something like a 'continue' statement for the outer most loop based on what happens in the conditional statement in the inner most loop.
Which would be a good method to achieve this, and how would it have to be implemented?
Edit: Next to the answer I accepted, I would also recommend Martin Bonner's answer, which also works perfectly fine and doesn't rely on goto.
for (int i = 0; i < max; i++){
Object & object1 = system.getAgent(i);
VectorOfStrings object_property1 = object1.getProperty();
for (int j = i + 1; j < max; j++){
Object & object2 = system.getObject(j);
VectorOfStrings object_property2 = object2.getProperty();
for (unsigned int k = 0; k < object_property1.size(); k++){
if (object_property1[k] == object_property2[k]){
//do something
break; //this aborts the inner most loop
//Additionally, I need the outer most loop to move on one iteration
}
}
}
}
So if the conditional statement in the 'k' loop is met, I want the 'i' loop to abort the current iteration and move on to the next one.
Also, since I'm new, the code might be inelegant, but please focus on this specific problem in your answers! Unless a general restructuring of the code might be the solution to the problem of course :)
Upvotes: 31
Views: 40548
Reputation: 6440
This may be implemented with goto
:
for (int i = 0; i < max; i++){
Object & object1 = system.getAgent(i);
VectorOfStrings object_property1 = object1.getProperty();
for (int j = i + 1; j < max; j++){
Object & object2 = system.getObject(j);
VectorOfStrings object_property2 = object2.getProperty();
for (unsigned int k = 0; k < object_property1.size(); k++){
if (object_property1[k] == object_property2[k]){
//do something
goto continue2; //this aborts the inner most loop
//Additionally, I need the outer most loop to move on one iteration
}
}
}
continue2:;
}
This is one of the rare cases when usage of goto
really simplifies code.
Upvotes: 55
Reputation: 213418
The most readable way to solve this classic problem is almost always to put the nested loops in a function. I don't know what the specific code is suppose to do, but here is some pseudo code you can base a solution on:
bool keep_going = true;
for (int i = 0; i < max && keep_going; i++)
{
Object& object1 = system.getAgent(i);
keep_going = !compare_objects(object1.getProperty(), i+1, max);
}
where compare_objects
is something like this:
inline bool compare_objects (const VectorOfStrings& obj_prop1, size_t begin, size_t end)
{
for(size_t i=begin; i<end; i++)
{
Object& obj2 = system.getObject(j);
VectorOfStrings obj_prop2 = obj2.getProperty();
for size_t j = 0; j < obj_prop1.size(); j++)
{
ifobj_prop1[j] == obj_prop2[j])
{
do_something();
return true;
}
}
}
return false;
}
Upvotes: 8
Reputation: 782
You can use lambda and use return stament to change the control. If you return true the lambda will end and outter "for" will "continue".
Compact version:
for(;;) {
[&]() {
for(;;) {
if(/*break condition here*/)
return;
}
}();
}
A more general template:
for(;;) {
auto innerLoop = [&]() {
for(;;) {
if(/*break condition here*/)
return true;
}
return false;
};
if(innerLoop())
continue;
}
For this case:
for (int i = 0; i < max; i++){
Object & object1 = system.getAgent(i);
VectorOfStrings object_property1 = object1.getProperty();
auto innerLoop = [](){
for (int j = i + 1; j < max; j++){
Object & object2 = system.getObject(j);
VectorOfStrings object_property2 = object2.getProperty();
for (unsigned int k = 0; k < object_property1.size(); k++){
if (object_property1[k] == object_property2[k]){
//do something
return true;
}
}
}
return false;
};
if(innerLoop())
continue;
}
Upvotes: 9
Reputation: 28987
I strongly recommend @alexeykuzmin0's approach, but if you have to work in an environment where goto
is forbidden, then the alternative (with annoying flag) is:
for (int i = 0; i < max; i++){
Object & object1 = system.getAgent(i);
VectorOfStrings object_property1 = object1.getProperty();
bool property_matched = false;
for (int j = i + 1; j < max && !property_matched; j++){
Object & object2 = system.getObject(j);
VectorOfStrings object_property2 = object2.getProperty();
for (unsigned int k = 0; k < object_property1.size(); k++){
if (object_property1[k] == object_property2[k]){
//do something
property_matched = true; // This will break the "j" loop
break; //this aborts the inner most loop
}
}
}
}
Upvotes: 7