2

So I've created a vector which contains product objects. The product has a int ID, string manufacturer and string productname. Lets say I've stored a few products by doing this

vector<product*>productlist;
 Product*p = new Product(123, "Sony", "C vaio laptop")
 Product*p1 = new Product(1234, "LG", "D 54 inch TV")
 Product*p2 = new Product(1235, "Lays", "A potato chips")
productlist.push_back(p);
productlist.push_back(p1);
productlist.push_back(p2);

I have a method called getproductname(){return productname;} which can be used to get the productname, and I can sort the productnames, but after that I have no idea how to continue as I don't know how to print the whole object by alphabetically of their productname.

Now I want to sort/print the 3 products by alphabetical order of their productname. How can I do that(the sorting part)? Sample output:

Products sorted alphabetically

Product ID1: 1235

Product manufacturer: Lays

Product name:A potato chips //name starts with A so it's the first output

Product ID2: 123

Product manufacturer: Sony

Product name: C vaio laptop

Product ID3: 1234

Product manufacturer: LG

Product name: D 54 inch TV //name starts with D so it's the last

I've tried inserting sort(productlist.begin(), productlist.end()); but it only works on vectors with string and not objects.

question asked was too vague/simple at first. Edited!

6
  • Are you storing pointers in the vector or the actual objects? Commented Jan 13, 2016 at 3:57
  • Is there a reason you are using pointers or could you store the Product objects in the vector directly? Commented Jan 13, 2016 at 3:58
  • I have a constructor product(int id, string manuf, string productname) and I'm storing the product object into the vector Commented Jan 13, 2016 at 4:01
  • But is there a reason you are using pointers? Why not just std::vector<Product> products ? Commented Jan 13, 2016 at 4:06
  • It points to my product class I guess? I'm sorry but I don't know how it even works. I referred to an example given by my lecturer in the past and this is how he does it. Commented Jan 13, 2016 at 4:17

3 Answers 3

9

The easiest way is to use std::sort() function from the standard library. You can try something like this:

#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

bool compareFunction (std::string a, std::string b) {return a<b;} 
//compare any way you like, here I am using the default string comparison

int main () 
{
  std::string myNames[] = {"Henry","Tom","Jafar","Alice","Bob","Cindy","Clara","Michael"};

  std::vector<std::string> myvector (myNames, myNames+8); //create vector from array

  std::sort(myvector.begin(),myvector.end(),compareFunction);//sort the vector


  std::cout << "Sorted vector:";
  for (std::vector<std::string>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

I would recommend you look into the documentation for more details on std::sort

Sign up to request clarification or add additional context in comments.

3 Comments

im so sorry but objects were stored in my vector instead of strings! I've edited my question.
Then you will have to supply your own comparison function for the objects. Consider overloading the operator<. look at Galik's answer
one can also use lambda instead of a seperate function for the comparator like so: auto compareFunc = [](std::string a, std::string b) {return a<b;};
5

The way to make sorting happen using STL containers is to define a comparator function that tells the std::sort algorithm how to compare the elements to place them in order. So we need to define a less than relationship which we can do by creating a less than operator for our Product class like this:

struct Product
{
    int ID = 0;
    std::string manuf;
    std::string name;

    Product(int ID, const std::string& manuf, const std::string& name)
    : ID(ID), manuf(manuf), name(name) // initialize members here
    {
    }

    // overloading the < operator enables functions
    // like std::sort to compare Product objects to
    // order them accordingly
    bool operator<(const Product& p) const
    {
        return name < p.name; // order by name
    }
};

Now if we send a container full of Product objects to std::sort they will be sorted according to name.

However, we need to sort Product objects through their pointers so we need another less than operator to hand to the std::sort function that dereferences the pointers before making the comparison using our comparator function.

// Function object to sort pointers
struct SortProductPointers
{
    // overload the function call operator
    bool operator()(const Product* lhs, const Product* rhs) const
    {
        // dereference the pointers to compare their targets
        // using the Product class's operator<(...) function
        return *lhs < *rhs;
    }
};

Now we have those two we can call our std::sort algorithm:

int main()
{
    std::vector<Product*> products;

    products.push_back(new Product(1, "Lays", "A potato chips"));
    products.push_back(new Product(3, "LG", "D 54 inch TV"));
    products.push_back(new Product(2, "Sony", "C vaio laptop"));

    // std::sort takes a third parameter which is the 
    // comparator function object    
    std::sort(products.begin(), products.end(), SortProductPointers());

    for(const auto* p: products)
        std::cout << p->ID << ": " << p->manuf << ", " << p->name << '\n';

    // Don't forget to delete all your Products
    for(auto* p: products)
        delete p;
}

2 Comments

it works for a vector of strings, but my vector contain objects!
@J.Will So your question changed and grew so did my answer :) Hope its clear enough.
0

You can also do it with a lambda implementation

    std::string myNames[] = {"Henry","Tom","Jafar","Alice","Bob","Cindy","Clara","Michael"};

  std::vector<std::string> myvector (myNames, myNames+8); //create vector from array
    
    std::sort(myvector.begin(), myvector.end(), [](const std::string & a, const std::string & b) -> bool
    {
        return a < b;
    });
    
    std::cout << "Sorted vector:";
  for (std::vector<std::string>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.