# Sorting a struct based on an array of ints

This is a discussion on Sorting a struct based on an array of ints within the C Programming forums, part of the General Programming Boards category; I wrote this code to take (1) a struct 'orig' and (2) an array of integers 'sorter', and create a ...

1. ## Sorting a struct based on an array of ints

I wrote this code to take (1) a struct 'orig' and (2) an array of integers 'sorter', and create a new struct 'temp' based on the sequence of the integers stored in the array 'sorter'. I'm essentially sorting the original 'orig' struct, but I don't want to lose or modify it, so I am just creating a new one: 'temp'.

The following code is a for loop that I am using to build the 'temp' struct using 'orig' and 'sorter'. Note that 'orig', 'sorter', and 'temp' are all 4 elements long. Also note that both 'orig' and 'temp' consist of 3 members: 'face', 'rank', and 'type'.
Code:
```  for(i=0;i<4;i++){
if (orig[i].rank==sorter[0]){
strcpy(temp[0].face,orig[i].face);temp[0].rank=orig[i].rank;temp[0].type=orig[i].type;
}
if (orig[i].rank==sorter[1]){
strcpy(temp[1].face,orig[i].face);temp[1].rank=orig[i].rank;temp[1].type=orig[i].type;
}
if (orig[i].rank==sorter[2]){
strcpy(temp[2].face,orig[i].face);temp[2].rank=orig[i].rank;temp[2].type=orig[i].type;
}
if (orig[i].rank==sorter[3]){
strcpy(temp[3].face,orig[i].face);temp[3].rank=orig[i].rank;temp[3].type=orig[i].type;
}```
The array of integers is sorted from highest to lowest (sorter[0] will be the highest number in the array, sorter[3] will be the lowest number in the array). The problem that I have with the code above is that it is not optimized for situations when 'sorter', the array of integers, contains multiples of the same int, (ex. sorter[1]==sorter[2]).

If sorter[1]==sorter[2], the new 'temp' struct that I am creating will be updated twice for the value of sorter[1] and twice again for the value of sorter[2]. Since the if statement for sorter[2] occurs after sorter[1], the members from the 'orig' struct if (orig[i].rank==sorter[2]) will update the 'temp' struct twice, and the members from the 'orig' struct if (orig[i].rank==sorter[1]) will not remain updated in 'temp' at all.

I have two questions pertaining to fixing this problem:

(1) Once the first if statement is true, is there a way to record the value of 'i' at that instant and then prevent 'i' from being set equal to that value for the rest of the execution of the for loop? 'i' is an element in the 'orig' struct, and I only want to use each 'orig' element once.
(2) Once an if statement is true, is there a way to make the code exit that particular if statement after performing the specific code that follows that if statement? I don't want the program have to evaluate the if statement any more than it needs to, and once an if statement is found to be true, it needs to perform whatever code that follows and then move on to the next if statement immediately.

If I can find the answer to both of these questions, I think I can change this code to function as desired. Perhaps I am constricting myself by using a for loop. Perhaps I should use a different approach to the problem.

2. A sort by pointer or index number, might be just the ticket. You can "sort" an array, without moving, anything.

Say you had an array of structs:

Code:
```/* sorting by using an index */

#include <stdio.h>

typedef struct {
int x;
int y;
}coord1;

int main(void) {
int i, j, temp;
int idx[10];  //our index array that gets sorted, instead
coord1 coord[10]; //our array of structs that needs sorting
for(i=0;i<10;i++) {
idx[i] = i;   //trippy, eh? ;)
coord[9-i].x = i;  //assign some values
}

//sort it, using the index array, only strucs never move
for(i=0;i<9;i++) {
for(j=i+1;j<10;j++) {
if(coord[idx[i]].x > coord[idx[j]].x) {
temp = idx[i];
idx[i] = idx[j];
idx[j] = temp;
}
}
}
printf("\n\n in sorted order:");
for(i=0;i<10;i++)
printf("\n %d", coord[idx[i]]);

printf("\n\n in acual order:");
for(i=0;i<10;i++)
printf("\n %d", coord[i]);

(void) getchar();
return 0;
}```

3. I need to figure out one thing, and I will be set.

If I have the following code:

Code:
```for(i=0;i<5;i++){
if (orig[i].rank==sorter[0]){
strcpy(temp[3].face,orig[i].face);temp[3].rank=orig[i].rank;temp[3].type=orig[i].type;

for(i=0;i<5;i++){
if (orig[i].rank==sorter[1]){
strcpy(temp[4].face,orig[i].face);temp[4].rank=orig[i].rank;temp[4].type=orig[i].type;
}
}
}
}```
How can I record the value of 'i' in the first if statement (when first if statement is true) and prevent it from being set equal to that value in the condition of the second for loop (i=0;i,5;i++ changes)? For example, the first if statement is true when i=1, therefore the second for loop condition contains something like i!=1.

I can't quite tell if the example code above does something like this or not. It doesn't compile, I'm very new to programming, and I don't know how to fix it.

4. When you nest loops that have counters in them to control some logic, you have to use different variables.

In your inner nested loop, use j, and look at the sorting portion of my previous post for a clear example of using i and j. These are the standard programming idiom (not just C), for two nested loop counter variables.