PDA

View Full Version : Comparing two QList with date time as parameter



rohitkk
9th June 2014, 10:12
Hi All,
Is there any way for sorting two QList of different objects.
for e.g. I have two POCO(Plain Old Cpp objects) Classes (Student & Employee), & both have CREATION_TIME field in db (consists when the record is created).
Now I have to sort this both QList (QList<Student> & QList<Employee>) by their CREATION_TIME.
Can it be done programmatically? or can it be achieved by some SQL query?

Any kind of help will be appreciated.

Thanks in Advance.

PS : CREATION_TIME is of type DATETIME (QDateTime).

wysota
9th June 2014, 10:16
What do you mean by "two lists of different objects"? Do you wish to get one list as a result or two separate lists, one for each source list?

rohitkk
9th June 2014, 10:18
What do you mean by "two lists of different objects"? Do you wish to get one list as a result or two separate lists, one for each source list?
It is two different lists.(To be compared by specific value i.e. CREATION_TIME)
e.g. QList<Student> & QList<Employee>.

PS : And I think the result will be stored in the other list after comparison.
for e.g.:


QList<QObject> listNew;
QList<Employee> listEmp;
QList<Student> listStud;

for(i=0;;i++)
if(listEmp.at(i).creTime<listStud.at(i).creTime)
listNew.add(listEmp.at(i));
else
listNew.add(listStud.at(i));


Pls ignore the mistakes as I am new to this technology & know very less about this.

Thanks.

Lesiok
9th June 2014, 10:24
Read about qSort (http://qt-project.org/doc/qt-4.8/qtalgorithms.html#qSort-2) function.

wysota
9th June 2014, 10:26
It is two different lists.(To be compared by specific value i.e. CREATION_TIME)
e.g. QList<Student> & QList<Employee>.

PS : And I think the result will be stored in the other list after comparison.
for e.g.:


QList<QObject> listNew;
QList<Employee> listEmp;
QList<Student> listStud;

for(i=0;;i++)
if(listEmp.at(i).creTime<listStud.at(i).creTime)
listNew.add(listEmp.at(i));
else
listNew.add(listStud.at(i));


Pls ignore the mistakes as I am new to this technology & know very less about this.

Thanks.

So... you have a list of type A, a list of type B and you want as a result a list of type C?

Do A and B have a common base class?

rohitkk
9th June 2014, 10:37
Read about qSort (http://qt-project.org/doc/qt-4.8/qtalgorithms.html#qSort-2) function.
I think qSort can be used to sort single list or list of Single data type.


So... you have a list of type A, a list of type B and you want as a result a list of type C?
Yes.As I cannot have list of type
QList<Student,Employee>, I have to declare a
QList<QObject> which will have the data for both 'Student' & 'Employee'.


Do A and B have a common base class?
No.

wysota
9th June 2014, 11:11
Do Student and Employee inherit QObject? That's very unlikely as QObject cannot be copied thus you cannot have a QList<QObject>, only QList<QObject*>.

If classes A and B do not have a common base class C then I suggest to create a structure marking indexes in the source lists:


struct Position {
enum { Student, Employee } Type;
Type list;
int index;
Position(Type l, int i) { list = l; index = i; }
Position() { l = Student; index = -1;}
};

then fill that list using two source lists:


QList<Position> positions;
for(int i=0;i<students.size();++i) {
positions << Position(Position::Student, i);
}

for(int i=0;i<employees.size();++i) {
positions << Position(Position::Employee, i);
}

And then sort that list using qSort (or std::sort) and a custom sorting function object that accepts the two source functions as parameters and then sorts the position list according to those two lists:


class SortFunctor {
public:
SortFunctor(const QList<Student> &students, const QList<Employee> &employees) : m_students(students), m_employees(employees) {}
bool operator()(const Position &p1, const Position &p2) const {
QDateTime dt1 = (p1.list == Student) ? m_students.at(p1.index).time : m_employees.at(p1.index). time;
QDateTime dt2 = (p2.list == Student) ? m_students.at(p2.index).time : m_employees.at(p2.index). time;
return dt1 < dt2;
}
};

In the end you'll get a list of Position objects sorted by time in the source lists:

qSort(positions.begin(), positions.end(), SortFunctor(students, employees));

Then you can use that list as indirect reference to the other two lists (like in the sorting functor).

Note: If original lists are already sorted by time then there is a simpler solution -- perform a merging step of the merge sort algorithm (i.e. iteratate over the two lists choosing from a list as long as the time is smaller than that of the current item in the other list) building the position list in O(m+n) time.

anda_skoa
9th June 2014, 11:44
Now I have to sort this both QList (QList<Student> & QList<Employee>) by their CREATION_TIME.

qSort() has an overload that allows you to specify a "less than" predicate, e.g. simple function returning bool and taking two of the objects



bool studentLessThanByCreationTime(const Student &s1, const Student &s2)
{
return s1.creationtime < s2.creationtime;
}




or can it be achieved by some SQL query?

Very likely, there is an "ORDER BY" keyword in SQL.

Cheers,
_

rohitkk
9th June 2014, 12:00
Hi All,
I think my question is misunderstood.
I can get the list of 'Student' & 'Employee' sorted by 'CREATION_TIME' by simply using "ORDER BY CREATION_TIME" in the end of sql query statement.
Hence, getting individual list sorted is not a challenge but sorting both the list of 'Student' & 'Employee' & merging into a different list is challenge.
I think now my question is more clear.

wysota
9th June 2014, 12:15
If you tell me how to merge a list of bananas and a list of airplanes into one list of shoes then I will tell you how to merge a list of students and a list of employees into a list of whatever else you can imagine. Without that the solution I gave you with a list of references to the other two lists is the closest you can get unless you make students and employees share a common base class exposing the creation time as one of its public functions.

In SQL you can select from an union of two tables, getting the merged list sorted by whatever you want that is shared between the two tables (e.g. creation time).

rohitkk
9th June 2014, 14:32
I have achieved this by using UNION,
Below is my query,

" SELECT CREATION_TIME,COL2,COL3 FROM 'student_info_table' UNION ALL SELECT CREATION_TIME,COL2,COL3 FROM 'employee_info_table' ORDER BY CREATION_TIME ASC"

Thank you all ,
for giving time & taking Interest.