By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,089 Members | 2,069 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,089 IT Pros & Developers. It's quick & easy.

Multi-column sort (urgent help needed)

P: n/a
Hello All,

I am reading a CSV (comma seperated value) file into a 2D array. I want
to be able to sort multiple columns (ala Excel), so I know for starters,
I cant be using the array, I need something more sophistictated like a
vector of row objects.

The data is of this format (same number of columns for each row):

A, x, y, z, ...
A, b, c, f, ...
A, s, b, m, ...
C, p, s, w, ...
C, a, s, u, ....

etc ...

Esentially, what I want to do is :

1). Read the data into memory (no brainer - I can do that)
2). Sort the data by specified columns (say column 2, and 4)

I would be very grateful if any one could show me how to do this using a
simple code example, or point me to a URL for some examples, or better
still point me to a library that is capable of doing this.

Many thanks in advance for your help

Ann

Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
You could use a public domain database library like
http://www.sqlite.org. "SQLite is a small C library that implements a
self-contained, embeddable, zero-configuration SQL database engine."
Jul 22 '05 #2

P: n/a
Dr. Ann Huxtable wrote:
I am reading a CSV (comma seperated value) file into a 2D array. I want
to be able to sort multiple columns (ala Excel), so I know for starters,
I cant be using the array, I need something more sophistictated like a
vector of row objects.

The data is of this format (same number of columns for each row):

A, x, y, z, ...
A, b, c, f, ...
A, s, b, m, ...
C, p, s, w, ...
C, a, s, u, ....

etc ...

Esentially, what I want to do is :

1). Read the data into memory (no brainer - I can do that)
2). Sort the data by specified columns (say column 2, and 4)

I would be very grateful if any one could show me how to do this using a
simple code example, or point me to a URL for some examples, or better
still point me to a library that is capable of doing this.


Look up the std::sort algorithm in the C++ Standard Library.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #3

P: n/a
In article <co**********@titan.btinternet.com>,
Dr. Ann Huxtable <an*********@research.de.edu> wrote:

I am reading a CSV (comma seperated value) file into a 2D array. I want
to be able to sort multiple columns (ala Excel), so I know for starters,
I cant be using the array, I need something more sophistictated like a
vector of row objects.
Yes, a vector of struct or class objects that represent rows, would be
more appropriate for this.
2). Sort the data by specified columns (say column 2, and 4)


You need to supply a custom comparison function to the standard sort()
function. Here's an example that I gave my students last year. Each
comparison function sorts by one field (column) only; to sort by more than
one field together, expand the comparison logic in the
function accordingly.

// profsort.cpp
//
// Demonstrates how to sort a vector of classes by supplying (a) a
// comparision function or (b) a comparison function object to the
// standard sort() function.
//----------------------------------------------------------------------

#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

//---------------------------------------------------------------------
// a simple class for storing data about professors

class Professor
{
public:
Professor (const string& initFN, const string& initLN,
const string& initOffice);
void Display() const;
friend int CompareByLastName (const Professor& lhs,
const Professor& rhs);
friend class CompareByOffice;
private:
string lastName, firstName, office;
};

// Constructor

Professor::Professor (const string& initFN, const string& initLN,
const string& initOffice)
: lastName(initLN), firstName(initFN), office(initOffice) {}

// A simple one-line display

void Professor::Display() const
{
cout << setw (15) << lastName
<< setw (10) << firstName
<< setw (20) << office
<< '\n';
}

// Comparison function for sorting by last name; it needs to
// be a friend function so it can access private data of the class

int CompareByLastName (const Professor& lhs, const Professor& rhs)
{
return (lhs.lastName < rhs.lastName);
}

// Here's another way to set up the comparison: a function object.
// This one compares by office location. This class needs to be
// a friend class of Professor so it can use private data.

class CompareByOffice
{
public:
int operator () (const Professor& lhs, const Professor& rhs)
{ return (lhs.office < rhs.office); };
};

//----------------------------------------------------------------------

void DisplayVector (const vector<Professor>& profs)
{
cout << '\n';
for (int k = 0; k < profs.size(); ++k)
{
profs[k].Display();
}
}

//----------------------------------------------------------------------
//----------------------------------------------------------------------

int main ()
{
ifstream profsfile ("profs.dat");
vector<Professor> profs;

// File format is one professor per line, with the fields separated
// by tabs

string firstName, lastName, office;
while (getline (profsfile, firstName, '\t')
&& getline (profsfile, lastName, '\t')
&& getline (profsfile, office, '\n'))
{
profs.push_back (Professor (firstName, lastName, office));
}
profsfile.close ();

cout << "\nBefore sorting:\n";
DisplayVector (profs);

// sort by last name, using an ordinary function for the comparison

sort (profs.begin(), profs.end(), CompareByLastName);

cout << "\nAfter sorting by last name:\n";
DisplayVector (profs);

// sort by office location, using a function object for the comparison

sort (profs.begin(), profs.end(), CompareByOffice());

cout << "\nAfter sorting by office:\n";
DisplayVector (profs);

cout << '\n';

return 0;
}

--
Jon Bell <jt*******@presby.edu> Presbyterian College
Dept. of Physics and Computer Science Clinton, South Carolina USA
Jul 22 '05 #4

P: n/a
"Jon Bell" <jt*******@presby.edu> wrote in message
news:co**********@jtbell.presby.edu...
You need to supply a custom comparison function to the standard sort()
function. Here's an example that I gave my students last year. Each
comparison function sorts by one field (column) only; to sort by more than
one field together, expand the comparison logic in the
function accordingly.
I would like to make a single comment/addition to your (excellent) example.
int CompareByLastName (const Professor& lhs, const Professor& rhs)
{
return (lhs.lastName < rhs.lastName);
} .... class CompareByOffice
{
public:
int operator () (const Professor& lhs, const Professor& rhs)
{ return (lhs.office < rhs.office); };
};
If one would like to simultaneously sort by two columns (e.g. sort by office
first, but then by name within the same office), one will want to replace
the second call to sort below with std::stable_sort.
sort (profs.begin(), profs.end(), CompareByLastName);

cout << "\nAfter sorting by last name:\n";
DisplayVector (profs);

// sort by office location, using a function object for the comparison

sort (profs.begin(), profs.end(), CompareByOffice());

stable_sort( ...same params... ); // will keep names ordered within
office

Alternatively, a comparison object doing both ordering operations at once
can
be provided to a single sort() call:

int CompareByOfficeAndLastName (const Professor& lhs, const Professor& rhs)
{
return (lhs.office < rhs.office)
|| ( !(rhs.office < lhs.office) && (lhs.lastName <
rhs.lastName) );
// return result of name compare if office compare does not provide an
order
}

hth -Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
Jul 22 '05 #5

P: n/a


Jon Bell wrote:
In article <co**********@titan.btinternet.com>,
Dr. Ann Huxtable <an*********@research.de.edu> wrote:
I am reading a CSV (comma seperated value) file into a 2D array. I want
to be able to sort multiple columns (ala Excel), so I know for starters,
I cant be using the array, I need something more sophistictated like a
vector of row objects.

Yes, a vector of struct or class objects that represent rows, would be
more appropriate for this.

2). Sort the data by specified columns (say column 2, and 4)

You need to supply a custom comparison function to the standard sort()
function. Here's an example that I gave my students last year. Each
comparison function sorts by one field (column) only; to sort by more than
one field together, expand the comparison logic in the
function accordingly.

// profsort.cpp
//
// Demonstrates how to sort a vector of classes by supplying (a) a
// comparision function or (b) a comparison function object to the
// standard sort() function.
//----------------------------------------------------------------------

#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

//---------------------------------------------------------------------
// a simple class for storing data about professors

class Professor
{
public:
Professor (const string& initFN, const string& initLN,
const string& initOffice);
void Display() const;
friend int CompareByLastName (const Professor& lhs,
const Professor& rhs);
friend class CompareByOffice;
private:
string lastName, firstName, office;
};

// Constructor

Professor::Professor (const string& initFN, const string& initLN,
const string& initOffice)
: lastName(initLN), firstName(initFN), office(initOffice) {}

// A simple one-line display

void Professor::Display() const
{
cout << setw (15) << lastName
<< setw (10) << firstName
<< setw (20) << office
<< '\n';
}

// Comparison function for sorting by last name; it needs to
// be a friend function so it can access private data of the class

int CompareByLastName (const Professor& lhs, const Professor& rhs)
{
return (lhs.lastName < rhs.lastName);
}

// Here's another way to set up the comparison: a function object.
// This one compares by office location. This class needs to be
// a friend class of Professor so it can use private data.

class CompareByOffice
{
public:
int operator () (const Professor& lhs, const Professor& rhs)
{ return (lhs.office < rhs.office); };
};

//----------------------------------------------------------------------

void DisplayVector (const vector<Professor>& profs)
{
cout << '\n';
for (int k = 0; k < profs.size(); ++k)
{
profs[k].Display();
}
}

//----------------------------------------------------------------------
//----------------------------------------------------------------------

int main ()
{
ifstream profsfile ("profs.dat");
vector<Professor> profs;

// File format is one professor per line, with the fields separated
// by tabs

string firstName, lastName, office;
while (getline (profsfile, firstName, '\t')
&& getline (profsfile, lastName, '\t')
&& getline (profsfile, office, '\n'))
{
profs.push_back (Professor (firstName, lastName, office));
}
profsfile.close ();

cout << "\nBefore sorting:\n";
DisplayVector (profs);

// sort by last name, using an ordinary function for the comparison

sort (profs.begin(), profs.end(), CompareByLastName);

cout << "\nAfter sorting by last name:\n";
DisplayVector (profs);

// sort by office location, using a function object for the comparison

sort (profs.begin(), profs.end(), CompareByOffice());

cout << "\nAfter sorting by office:\n";
DisplayVector (profs);

cout << '\n';

return 0;
}

Thanks very much Jon, this is just what I needed !

Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.