executing a for loop or once depending on a test

Z

zebulon

Hi,

I am trying to avoid redundancy in my code and would like to know if
there is an elegant solution for this.

Let's say I have 2 vectors (va and vb) that may contain Int and String
elements respectively, or be empty. I'd like to generate all
combinations of Int/String so I could use a nested loop :

for (vector<int>::iterator vai = va.begin(); vai != va.end(); ++vai)
{
for (vector<string>::iterator vbi = vb.begin(); vbi != vb.end(); +
+vbi)
{
// create the object
Object* oneobject = new Object();
// store vai and vbi combination
oneobject->addInt(*vai);
oneobject->addString(*vbi);
// store the object pointer somewhere;
vector_objects.push_back(oneobject);
}
}

The problem here is that if one of my vectors is empty, no object at
all will be created.

So I solved it using some tests:

if (!va.empty() && vb.empty()) //only ints
{
for (vector<int>::iterator vai = va.begin(); vai != va.end(); +
+vai)
{
// create object
oneobject->addInt(*vai);
// store
}
}
else if (va.empty() && !vb.empty()) //only strings
for (vector<int>::iterator vbi = vb.begin(); vbi != vb.end(); ++vbi)
{
// etc...
}
else if (!va.empty() && !vb.empty()) //int and strings
{
for (vector<int>::iterator vbi = vb.begin(); vbi != vb.end(); +
+vbi)
{
for (vector<int>::iterator vbi = vb.begin(); vbi != vb.end(); +
+vbi)
{
// etc...
}
}
}
else if (!va.empty() && !vb.empty()) //no int no strings
{
// etc...
}

The problem is that there is a lot of code redundency (common parts in
the loops), and if there are more than two vectors, the number of if
statements would be impossible to manage.

Actually, instead of Int and String, if I have pointers to objects, I
know I could use inheritance/polymorphism in order to store them in
the same container. However, the objects can be heterogenous and
inheritence is not suitable.

Is there an elegant way to avoid all the if statements ?
 
J

Jorgen Grahn

Hi,

I am trying to avoid redundancy in my code and would like to know if
there is an elegant solution for this.

Let's say I have 2 vectors (va and vb) that may contain Int and String
elements respectively, or be empty. I'd like to generate all
combinations of Int/String so I could use a nested loop :

for (vector<int>::iterator vai = va.begin(); vai != va.end(); ++vai)
{
for (vector<string>::iterator vbi = vb.begin(); vbi != vb.end(); ++vbi)
{
// create the object
Object* oneobject = new Object();
// store vai and vbi combination
oneobject->addInt(*vai);
oneobject->addString(*vbi);
// store the object pointer somewhere;
vector_objects.push_back(oneobject);
}
}

Why the new? Why not simply:

for (vector<int>::iterator vai = va.begin(); vai != va.end(); ++vai)
{
for (vector<string>::iterator vbi = vb.begin(); vbi != vb.end(); ++vbi)
{
vector_objects.push_back(Object(*vai, *vbi));
}
}
The problem here is that if one of my vectors is empty, no object at
all will be created.

Isn't that part of the definition of "all combinations"? Combine
a set of N elements with one of M elements, and you get N*M pairs.
N*0 == 0.

/Jorgen
 
Z

zebulon

Why the new? Why not simply:

  for (vector<int>::iterator vai = va.begin(); vai != va.end(); ++vai)
    {
      for (vector<string>::iterator vbi = vb.begin(); vbi != vb..end(); ++vbi)
        {
          vector_objects.push_back(Object(*vai, *vbi));
        }
    }

Hi,

I would have the same issue if one of the vectors is empty (as
discussed below).

Isn't that part of the definition of "all combinations"? Combine
a set of N elements with one of M elements, and you get N*M pairs.
N*0 == 0.

Actually, they are not real combinations in the mathematical sense,
more like conditional combinations, if elements are there. But if one
of the vector is empty and the other one is not, we should still
create objects with the elements of the non-empty vector.

Regards,
Eric
 
Z

zebulon

Just a side observation, if your 'vb' and 'va' do not change during the
execution of these loops, it's better to get the iterator values once
before entering the very first loop.  It may look like premature
optimization, but I've seen it with my own three eyes how long a simple
function call can take (relatively speaking).  So, consider

Hi Victor,

Point taken, thanks for the advice.

So, what you're saying that it should be created...  It's not obvious
from your requirement.  If there aren't any ints or strings, there
shouldn't be any combinations, no?  Nothing to combine, right?...

Actually I should have at least one object created (see below).
It would seem you're asking for an algorithm.  Consider the newsgroup
'comp.programming' for such generic requests.  An algorithm is not
language-specific, usually.

What is it you'd like to end up with?  Let's say you have collection A,
collection B, and collection C (possibly more).  Let's further say that
collection A contains 2 objects, collection B contains one, and
collection C is empty.  Let's name objects 'a0', 'a1', and 'b0'.  What
combinations are you looking for?  Please enumerate *all*.

I realise it was not clear. It is more an accumulation rather than a
combination.

If va contains nothing and vb contains 3 strings, I should end up with
3 objects, each containing 1 string from vb. If va contains 2 ints and
vb is empty, I should get 2 objects, each containing 1 int. If va
contains 2 ints and vb 3 strings, then I should get 6 objects, each
containing a combination (va_element, vb_element). Therefore it is
more like a "conditional combination" that I am looking for.

Regards,
Eric
 
Z

zebulon

I am replying to myself, because I thought of a possible solution: if
one or both vectors are empty, I should add a "dummy" element, so that
each loop is executed at least once. Then, the object would add an
element only if it is not the "dummy" one.

What do you think?

Eric
 
D

Daniel T.

I am replying to myself, because I thought of a possible solution: if
one or both vectors are empty, I should add a "dummy" element, so that
each loop is executed at least once. Then, the object would add an
element only if it is not the "dummy" one.

What do you think?

Conditionally, putting a dummy object in the vectors that are empty
only works if (a) there is some reasonable default and (b) you can
leave the dummies in the vectors at the end (otherwise you have to
conditionally remove them.)

If both of those conditions are met, then that would probably be the
best solution.
 
A

acehreli

if
one or both vectors are empty, I should add a "dummy" element, so that
each loop is executed at least once. Then, the object would add an
element only if it is not the "dummy" one.

What do you think?

I think it qualifies as a manifestation of the "null object pattern"
and I like it. :)

Ali
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top