Hi,

I've got a vector of structs populated with the following fields:

double double double double (unsigned int) (unsigned int) string

I want to take each line in that vector (call it OldVec), and
1. transfer it to a new vector of structures
2. add a string identifier at the end of said line.

So I can create a new vector of structures with the above 7 variables and add a string to it. Let's call that NewVec and it would contain:

double double double double (unsigned int) (unsigned int) string string.

How can I do the copy from OldVec to NewVec and insert/append the string (would just be a few characters like "identifier") at the end of the line that's copied over?

Thanks,
TR

One way would be to overload the '=' operator in a new struct that inherits the old struct. something like this:

struct MainStruct
{
public:
    double a;
    double b;
    double c;
    double d;
    unsigned e;
    unsigned f;
    string g;
};
struct MyStruct : MainStruct
{
public:
    string h;
    MyStruct MyStruct::operator= (MainStruct &other)
    {       
        a=other.a;
        b=other.b;
        c=other.c;
        d=other.d;
        e=other.e;
        f=other.f;
        g=other.g;
        h="";
        return *this;
    }
};

int main()
{
    vector<MainStruct> OldVec;
    vector<MyStruct> NewVec;
    MainStruct temp;
    temp.a = 1;
    temp.b = 2;
    temp.c = 3;
    temp.d = 4;
    temp.e = 5;
    temp.f = 6;
    temp.g = "A";
    OldVec.push_back(temp);
    for(int i = 0; i < OldVec.size();i++)
    {
        stringstream Identifier;
        MyStruct temp;
        temp.operator=(OldVec[i]);
        Identifier << "Id"<< i * 100;
        temp.h = Identifier.str();
        NewVec.push_back(temp);    
    }
    return 0;
}    

Edited 3 Years Ago by tinstaafl

Get your assignment opertators and constructors correct and copying one to the other becomes a simple std::copy call.

#include <vector>
#include <string>
#include <algorithm>
#include <iterator>

using std::vector;
using std::string;

struct MainStruct
{
public:
    double a;
    double b;
    double c;
    double d;
    unsigned e;
    unsigned f;
    string g;

    MainStruct() :
        a(0.0),
        b(0.0),
        c(0.0),
        d(0.0),
        e(0),
        f(0),
        g()
    {
    }

    MainStruct(const MainStruct&cpy) :
        a(cpy.a),
        b(cpy.b),
        c(cpy.c),
        d(cpy.d),
        e(cpy.e),
        f(cpy.f),
        g(cpy.g)
    {
    }

    const MainStruct& operator= (const MainStruct &cpy)
    {
      if (this != &cpy)
      {
        a=cpy.a;
        b=cpy.b;
        c=cpy.c;
        d=cpy.d;
        e=cpy.e;
        f=cpy.f;
        g=cpy.g;
      }

      return *this;
    }
};

struct MyStruct : MainStruct
{
public:
  string h;

  MyStruct() :
      MainStruct(),
      h()
  {       
  }

  MyStruct(const MyStruct &cpy) :
      MainStruct(cpy),
      h(cpy.h)
  {       
  }

  MyStruct(const MainStruct &other) :
      MainStruct(other),
      h()
  {       
  }

  const MyStruct& operator= (const MainStruct &other)
  {
    MainStruct::operator=(other);
    h="";

    return *this;
  }
};

int main()
{
  vector<MainStruct> OldVec;
  vector<MyStruct> NewVec;

  // Populate OldVec
  OldVec.resize(1000);

  // Clear NewVec if required but in this test program it is already empty

  // Resize NewVec to prevent lots of memory reallocations
  NewVec.reserve(OldVec.size());

  // Copy new to old
  std::copy(OldVec.begin(), OldVec.end(), std::back_inserter(NewVec));

  return 0;
}    

Although this does miss out on the assigning a value to the new string, you could possibly do something with std::transform too which takes an opertor that you let you assign the final parameter (structure definitions as above)

class addIdentity
{
public:
  addIdentity() : id(1)
  {
  }

  MyStruct operator()(const MainStruct& cpy)
  {
    MyStruct newStruct(cpy);
    std::stringstream identifer;

    identifer << "Identifier" << id;
    newStruct.h = identifer.str();
    id++;

    return newStruct;
  }

private:
  int id;
};

int main()
{
  vector<MainStruct> OldVec;
  vector<MyStruct> NewVec;

    // Populate OldVec
  OldVec.resize(1000);

    // Clear NewVec if required but in this test program it is already empty

    // Resize NewVec to prevent lots of memory reallocations
    NewVec.reserve(OldVec.size());

    // Copy new to old
    std::transform(OldVec.begin(), OldVec.end(), std::back_inserter(NewVec), addIdentity());

  return 0;
}    

Edited 3 Years Ago by Banfa

Tinstaafl,

Very elegant solution, will try that first.

Banfa, thank you for chiming in too, will have to study your code.

Hi Tinstaafl,

I'm having trouble understanding what's going on from lines 34 on to 42. If my OldVec already contains data (in my program), why the pushback into it on line 42?

And then line 48: why the i * 100 part?

thanks.

30.int main()
31.{
32.    vector<MainStruct> OldVec;
33.    vector<MyStruct> NewVec;
34.    MainStruct temp;
35.    temp.a = 1;
36.    temp.b = 2;
37.    temp.c = 3;
38.    temp.d = 4;
39.    temp.e = 5;
40.    temp.f = 6;
41.    temp.g = "A";
42.    OldVec.push_back(temp);
43.    for(int i = 0; i < OldVec.size();i++)
44.    {
45.        stringstream Identifier;
46.        MyStruct temp;
47.        temp.operator=(OldVec[i]);
48.        Identifier << "Id"<< i * 100;
49.        temp.h = Identifier.str();
50.        NewVec.push_back(temp);    
51.    }
52.    return 0;
53.}    

Also, I came across this:

std::vector<type> newvector(oldvector);

as an example of using a vector's constructor to quickly make a new vector with the contents of the original.

I tried that on my code and it worked, but how would one append a string at the end of each line in the vector. I keep wanting to pushback a string into the vector, but since it originally contains 7 variables only, it won't take the string. Maybe I should modify the original structure and add a string to it?

lines 34-42 just add an object to oldvec, nothing special there. If your oldvec is already full of data just ignore that part.

Line 48 is just one way of using the loop to set the id number

The MyStruct that I sent you inherits from the MainStruct. This way it contains all the same fields plus the extra one in MyStruct.

The 'operator=' routine copies the fields from the MainStruct into the MyStruct and initializes the extra string, not always necessary but generally a good practice. Since that string is a part of MyStruct, it's simply a matter of giving it a value.

Edited 3 Years Ago by tinstaafl

@toneranger, if you have further questions related to this please post them in this thread rather than PM'ing me.

Hi All,

Well I've been stuck for a while here. Have tried implementing prior suggestions but no luck at all. So I'm trying another approach below by trying to add a function called TransfertoSwingID which will transfer a line of data held in a struct contained in a vector to a new vector of structs. I have no idea however of how to implement this, syntax wise.

Any help would be greatly appreciated. Thanks.

    int main(int argc, char* argv[]) 
    { 

    if (argc != 2) 
    { 

    std::cerr << 

    "Usage: " << argv[0] << " filename " << std::endl; 

    return EXIT_FAILURE; 
    } 


    PriceList prices; 

    ReadPricesFromFile(argv[1], prices); 
    if (prices.size() < 2)
        std::cout << "Vector size less than 2!" << std::endl;
    else
        std::cout << "Vector has 2 or more elements" << std::endl;



    std::vector<PriceInfo>::iterator it; 
    it = prices.begin();
    advance (it, 2);



    for (;it!= prices.end();) 
    { 

        if (it->Low > (it-1)->Low) 

         { 

            if ((it-1)->Low <= (it-2)->Low) 

             TransferToSwingID(0, *(it-1)); //( *(it-1) is likely wrong syntax)


            }


        {
            if (it->High < (it-1)->High)


            {
                if((it-1)->High >= (it-2)->High)
                TransferToSwingID(1, *(it-1)); (how does one pass the contents pointed to by iterator it?)

            }
        }


    ++it;
    } 

    int TransferToSwingID (int type, struct PriceInfo&)

    {
        struct SwingIdentified
        {
        double Id_Open; 

        double Id_High; 

        double Id_Low; 

        double Id_Close; 

        unsigned int Id_Volume; 

        unsigned int Id_Time; 
        std::string Id_Date; 

        std::string Identifier; 
        };


        // some code here to transfer the contents of *(it-1) 
        // to a new vector of struct of type SwingIdentified

        if (int type=0)

                std::string Identifier = "Swing Low";

        else if (int type=1)

                std::string Identifier = "Swing High";



    typedef std::vector<SwingIdentified> SwingPoints;

    }



    char quitKey;

    std::cout << "Press q to quit" << std::endl;

    std::cin >> quitKey;

    return EXIT_SUCCESS; 
    } 
This article has been dead for over six months. Start a new discussion instead.