Sorting a TArray of structs

Hi all,
hope you guys can give me a hand with this.
Let’s imagine I have a TArray of 10 structs:

struct testStruct { int32 a; int32 b; int32 c }

Its content is for example this (first column are indexes):

0: 5, 4, 5
1: 1, 4, 5
2: 5, 4, 7
3: 7, 1, 5
4: 7, 2, 5
5: 3, 6, 7
6: 2, 4, 5
7: 1, 1, 7
8: 4, 1, 7
9: 6, 2, 7

How would I sort it on a, so to have this output?

0: 1, 4, 5
1: 1, 1, 7
2: 2, 4, 5
3: 3, 6, 7
4: 4, 1, 7
5: 5, 4, 5
6: 5, 4, 7
7: 6, 2, 7
8: 7, 1, 5
9: 7, 2, 5

Thanks in advance!

This suspiciously looks like a homework assignment, but look at defining a comparison operator for your struct.

There might be an easier way, but the way I’ve done it in the past is create a class that overloads operator(). It would look something like

class Sorter
{
public:
	bool operator()(const testStruct& x, const textStruct& y) const;
};

Implement your comparison however you want in that function and just pass in instance of the Sorter class to TArray::Sort.

TArray has a function for sorting

In order to work with your struct or class you need to override > operator that should declere if inputed A is bigger the B, then soft function to the rest with help of that operator

Yeah, I wish. :wink:
I’m looking into that, thanks.

hey ,
can it be done with normal structs, or should I make my structs into USTRUCTs? Could you show me any examples? This is still uncharted territory for me :stuck_out_tongue:
Thanks!

Well, I was going through a rabbit hole here… I tried to transform my c++ structs into USTRUCTs and failed (haven’t understood how to declare them in my header… sigh), then I tried to override the operator in the classic structs, and failed too.

In the end I solved by just implementing a bubble sort in my function like this:

// where testStructList is a TArray<testStruct *>

int32 iterations = testStructList .Num() - 1;
while (iterations > 0)
{
	for (int32 x = 0; x < testStructList .Num() - 1; x++)
	{
		if (testStructList [x]->a > testStructList [x + 1]->a)
		{
			testStructList .Swap(x, x + 1);
		}
	}
	iterations--;
}

Hey,

You can sort by using TArray’s Sort member function and a lambda (C++11 feature) which describes how your elements are to be sorted. If you want to sort by a, then b, then c, then you should have something like:

Array.Sort([](const testStruct& Lhs, const testStruct& Rhs) -> bool {
    // sort by a
    if (Lhs.a < Rhs.a) return true; 
    if (Lhs.a > Rhs.a) return false;

    // sort by b, but only if 'a's were equal
    if (Lhs.b < Rhs.b) return true; 
    if (Lhs.b > Rhs.b) return false;

    // sort by c, but only if 'a's and 'b's were equal
    return Lhs.c < Rhs.c;
});

Hope this helps,

Steve

1 Like

Or if you just want to sort by a and keep structs with equal 'a’s in the same relative order, then you can use:

Array.StableSort([](const testStruct& Lhs, const testStruct& Rhs) {
    return Lhs.a < Rhs.b;
});

Steve

Anything that support > operator and in struct you can override it

your code only sorts the ‘a’ field. You need ‘b’ and ‘c’ accounted for. If the a’s are equal then do the same test on b. If the a’s and b’s are equal, then do the same test on ‘c’.

DUDE! You just saved me sooo much time figuring out how to sort my struct for my targeting component lol Thanks! (Struct just contains ACharacter* Target, FString TargetName, and float TargetDistance). I’ve been trying to figure out how to sort by distance lol.

It should be noted that since my earlier reply, we now have a more convenient algorithm for this kind of thing:

Algo::SortBy(ArrayOfMyStruct, &MyStruct::TargetDistance);

Steve

3 Likes