How to sort a CArray with minimum effort
-
I have a CArray of structs that I want to be able to sort. Ie:
struct _Blah_
{
CString Name; // I'll be using this for comparison in this case
CSomeOtherStruct other;
DWORD dwSomething;
};
CArray<_Blah_, _Blah_&> BlahArray;The C libs come with a
sort
command that takes a compare function, but that does binary swaps. That may be fine for very basic structs in a CArray, but not if it is a class with virtual methods, etc. I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area! Thanks, Iain. -
I have a CArray of structs that I want to be able to sort. Ie:
struct _Blah_
{
CString Name; // I'll be using this for comparison in this case
CSomeOtherStruct other;
DWORD dwSomething;
};
CArray<_Blah_, _Blah_&> BlahArray;The C libs come with a
sort
command that takes a compare function, but that does binary swaps. That may be fine for very basic structs in a CArray, but not if it is a class with virtual methods, etc. I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area! Thanks, Iain.Iain Clarke wrote:
I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area!
I dont normaly use CArray, but with std::vector, having your vectored classes have an
operator<</code> and `operator!=` would be enough. Let's think the unthinkable, let's do the undoable, let's prepare to grapple with the ineffable itself, and see if we may not eff it after all. **Douglas Adams, "Dirk Gently's Holistic Detective Agency"**
-
I have a CArray of structs that I want to be able to sort. Ie:
struct _Blah_
{
CString Name; // I'll be using this for comparison in this case
CSomeOtherStruct other;
DWORD dwSomething;
};
CArray<_Blah_, _Blah_&> BlahArray;The C libs come with a
sort
command that takes a compare function, but that does binary swaps. That may be fine for very basic structs in a CArray, but not if it is a class with virtual methods, etc. I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area! Thanks, Iain.Iain Clarke wrote:
Feel free to give me pointers to some vector::sort library or such...
I don't know what you are looking for exactly but the STL does have sorting algorithms. You can have a look here[^] (don't look at how he is inheriting from std::vector, because, in my opinion, it is not really the way to do). The function swap two items, meaning that it uses the assignement operator and the copy constructor (not sure about this one). You could override this operator for your structure if you want to make it more efficient (if possible). I don't really see how you could sort, without swapping items anyway... Does that more or less answer your question ?
Cédric Moonen Software developer
Charting control [v1.5] OpenGL game tutorial in C++ -
I have a CArray of structs that I want to be able to sort. Ie:
struct _Blah_
{
CString Name; // I'll be using this for comparison in this case
CSomeOtherStruct other;
DWORD dwSomething;
};
CArray<_Blah_, _Blah_&> BlahArray;The C libs come with a
sort
command that takes a compare function, but that does binary swaps. That may be fine for very basic structs in a CArray, but not if it is a class with virtual methods, etc. I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area! Thanks, Iain.Please check the knowledge base article from MSDN How to use the quick-sort function to sort MFC CArray-derived classes on the MFC and Visual C++ run-time library[^]
-Sarath. "Great hopes make everything great possible" - Benjamin Franklin
My blog - Sharing My Thoughts, An Article - Understanding Statepattern
-
Iain Clarke wrote:
I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area!
I dont normaly use CArray, but with std::vector, having your vectored classes have an
operator<</code> and `operator!=` would be enough. Let's think the unthinkable, let's do the undoable, let's prepare to grapple with the ineffable itself, and see if we may not eff it after all. **Douglas Adams, "Dirk Gently's Holistic Detective Agency"**
Thanks - looks more elegant then writing my own predicate! Iain.
-
Iain Clarke wrote:
Feel free to give me pointers to some vector::sort library or such...
I don't know what you are looking for exactly but the STL does have sorting algorithms. You can have a look here[^] (don't look at how he is inheriting from std::vector, because, in my opinion, it is not really the way to do). The function swap two items, meaning that it uses the assignement operator and the copy constructor (not sure about this one). You could override this operator for your structure if you want to make it more efficient (if possible). I don't really see how you could sort, without swapping items anyway... Does that more or less answer your question ?
Cédric Moonen Software developer
Charting control [v1.5] OpenGL game tutorial in C++Cedric Moonen wrote:
Does that more or less answer your question ?
Yes thanks - the prevailing winds are blowing in STL's direction. I'll try jwurmbach's idea of providing comparison operator's in my own struct first - seems like less heavy lifting. Iain.
-
Thanks - looks more elegant then writing my own predicate! Iain.
If its just about the predicates, I also like boost.orgs lambda-lib[^] With it, you can write the predicate exactly where you need it, not somewhere else. Comes in handy when your classes do not have the one, inherent order, but instead need to be sorted by varying criteria.
Let's think the unthinkable, let's do the undoable, let's prepare to grapple with the ineffable itself, and see if we may not eff it after all.
Douglas Adams, "Dirk Gently's Holistic Detective Agency" -
Please check the knowledge base article from MSDN How to use the quick-sort function to sort MFC CArray-derived classes on the MFC and Visual C++ run-time library[^]
-Sarath. "Great hopes make everything great possible" - Benjamin Franklin
My blog - Sharing My Thoughts, An Article - Understanding Statepattern
Thanks for that. Interesting article. STL's
vector
andsort
are looking more elegant, but I've used a lot of CArray's over the years... Decisions... decisions! Iain. -
Iain Clarke wrote:
I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area!
I dont normaly use CArray, but with std::vector, having your vectored classes have an
operator<</code> and `operator!=` would be enough. Let's think the unthinkable, let's do the undoable, let's prepare to grapple with the ineffable itself, and see if we may not eff it after all. **Douglas Adams, "Dirk Gently's Holistic Detective Agency"**
Just added a comparison, and it works a treat, thanks! Iain.
struct NamedPos
{
CString Name;
... other member data herebool operator < (NamedPos const &p) const;
}
bool NamedPos::operator < (NamedPos const &p) const
{
return (Name.Compare (p.Name) < 0);
}...
NamedPos p;
p.Name = "1";
m_NamedPositions.push_back (p);
p.Name = "3";
m_NamedPositions.push_back (p);
p.Name = "2";
m_NamedPositions.push_back (p);
p.Name = "5";
m_NamedPositions.push_back (p);
p.Name = "4";
m_NamedPositions.push_back (p);std::sort (m\_NamedPositions.begin(), m\_NamedPositions.end ());
-
Just added a comparison, and it works a treat, thanks! Iain.
struct NamedPos
{
CString Name;
... other member data herebool operator < (NamedPos const &p) const;
}
bool NamedPos::operator < (NamedPos const &p) const
{
return (Name.Compare (p.Name) < 0);
}...
NamedPos p;
p.Name = "1";
m_NamedPositions.push_back (p);
p.Name = "3";
m_NamedPositions.push_back (p);
p.Name = "2";
m_NamedPositions.push_back (p);
p.Name = "5";
m_NamedPositions.push_back (p);
p.Name = "4";
m_NamedPositions.push_back (p);std::sort (m\_NamedPositions.begin(), m\_NamedPositions.end ());
Iain Clarke wrote:
it works a treat
Great! Actually, operator overloading is a good thing! :)
Let's think the unthinkable, let's do the undoable, let's prepare to grapple with the ineffable itself, and see if we may not eff it after all.
Douglas Adams, "Dirk Gently's Holistic Detective Agency" -
I have a CArray of structs that I want to be able to sort. Ie:
struct _Blah_
{
CString Name; // I'll be using this for comparison in this case
CSomeOtherStruct other;
DWORD dwSomething;
};
CArray<_Blah_, _Blah_&> BlahArray;The C libs come with a
sort
command that takes a compare function, but that does binary swaps. That may be fine for very basic structs in a CArray, but not if it is a class with virtual methods, etc. I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area! Thanks, Iain.The 'cheat' I generally use for this is a bit of a zen solution. I don't sort the array at all :) Instead I keep a parallel array of simple unsigned integers and I sort that and use it as an index into my array of complex objects. I use the standard sort algorithums but my comparator functions, instead of just comparing integers uses them to look up the real array and returns a comparison result dependent on what it finds there. If you dig around in the source of my constructional patterns article [^] you'll find an indexed list class, possibly even templated so you use it with your data structures.
"The secret of happiness is freedom, and the secret of freedom, courage." Thucydides (B.C. 460-400)
-
The 'cheat' I generally use for this is a bit of a zen solution. I don't sort the array at all :) Instead I keep a parallel array of simple unsigned integers and I sort that and use it as an index into my array of complex objects. I use the standard sort algorithums but my comparator functions, instead of just comparing integers uses them to look up the real array and returns a comparison result dependent on what it finds there. If you dig around in the source of my constructional patterns article [^] you'll find an indexed list class, possibly even templated so you use it with your data structures.
"The secret of happiness is freedom, and the secret of freedom, courage." Thucydides (B.C. 460-400)
"The best way to sort is to not sort at all". Very wax-on, wax-off... My structures are not highly horrible to swap about, luckily, but I can see your method being very useful if copying is an expensive or impossible process (ie, open DB handles are a classic baddie). As you normally give good answers, I assume your articles are worth a peek too... Iain.
-
"The best way to sort is to not sort at all". Very wax-on, wax-off... My structures are not highly horrible to swap about, luckily, but I can see your method being very useful if copying is an expensive or impossible process (ie, open DB handles are a classic baddie). As you normally give good answers, I assume your articles are worth a peek too... Iain.
Thanks for the vote of confidence, it's nice to be able to actually point someone at some relevant code for a change. I'm always finding myself wanting to refer to code, in answers to questions, which I either can't post or no longer have or worse still know that I must have but can't find.
"The secret of happiness is freedom, and the secret of freedom, courage." Thucydides (B.C. 460-400)
-
I have a CArray of structs that I want to be able to sort. Ie:
struct _Blah_
{
CString Name; // I'll be using this for comparison in this case
CSomeOtherStruct other;
DWORD dwSomething;
};
CArray<_Blah_, _Blah_&> BlahArray;The C libs come with a
sort
command that takes a compare function, but that does binary swaps. That may be fine for very basic structs in a CArray, but not if it is a class with virtual methods, etc. I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area! Thanks, Iain.Iain Clarke wrote:
How to [...] with minimum effort
Uhmmmmmmmmmmmmm, what a lazy guy. :rolleyes: :-D
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles] -
Iain Clarke wrote:
How to [...] with minimum effort
Uhmmmmmmmmmmmmm, what a lazy guy. :rolleyes: :-D
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
[My articles]CPallini wrote:
what a lazy guy.
Isn't that the best bit about programming? The lazy way is often the best one. Less typing -> less bugs. That only works if you're lazy over the long term though... Short term laziness leads to more work overall. (And yes, I know you were getting at me. Sigh... I'm such a martyr...) Iain. ps, "Infamy, infamy, they've all got it in for me!".
-
I have a CArray of structs that I want to be able to sort. Ie:
struct _Blah_
{
CString Name; // I'll be using this for comparison in this case
CSomeOtherStruct other;
DWORD dwSomething;
};
CArray<_Blah_, _Blah_&> BlahArray;The C libs come with a
sort
command that takes a compare function, but that does binary swaps. That may be fine for very basic structs in a CArray, but not if it is a class with virtual methods, etc. I could write a sort function for my particular array / class combo, but I'm sure there's a more elegant way of doing this... Feel free to give me pointers to some vector::sort library or such... I'm a novice in that area! Thanks, Iain.Unless it's a trivial structure, if I need to sort an array, I usually use a pointer array. Swapping items then becomes just swapping the pointer.
Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke