Search code examples
javaarrayssortingmultidimensional-arraycolumnsorting

Sorting a 2d array by values in more than one column


I want to build a method in Java for sorting an array according to values in more than a given column. Let me explain that with an example (matrix array):

int matrix[][] = {
        {0,2,432},{1,1,282},{2,2,456},{3,4,191},{4,5,293},
        {5,2,475},{6,2,491},{7,5,171},{8,5,134},{9,3,354}};

I need to sort every triplet according to the second position in decreasing order. After that, I need to sort the triplet in increasing order according to the third position.

The code that I'm using for that is:

import java.util.*;

public class sort2DMatrixByColumn {
    // Function to sort by column
    public static void sortByColumn(int arr[][], int col) {
        // Using built-in sort function Arrays.sort
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            // Compare values according to columns
            public int compare(final int[] entry1,
                               final int[] entry2) {

                if (entry1[col] < entry2[col])
                    return 1;
                else
                    return -1;
            }
        }); // End of function call sort().
    }

    // Driver Code
    public static void main(String args[]) {
        int matrix[][] = {
                {0,2,432},{1,1,282},{2,2,456},{3,4,191},{4,5,293},
                {5,2,475},{6,2,491},{7,5,171},{8,5,134},{9,3,354}};

        // Sort this matrix by 2rd Column
        int col = 2;
        sortByColumn(matrix, col - 1);

        // Display the sorted Matrix
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++)
                System.out.print(matrix[i][j] + " ");
            System.out.println();
        }
    }
}

The output of the previously described code is:

[[8,5,134],[7,5,171],[4,5,293],[3,4,191],[9,3,354],
 [6,2,491],[5,2,475],[2,2,456],[0,2,432],[1,1,282]]

But the output needed must be:

[[8,5,134],[7,5,171],[4,5,293],[3,4,191],[9,3,354],
 [0,2,432],[2,2,456],[5,2,475],[6,2,491],[1,1,282]]

Please note that according to the second position we have the following: 5,5,5,4,3,2,2,2,2,1 (decreasing order) and according to the third position the order is: 134,171,293 (for the triplets with a "5" in the second position), 191 (for the triplet with a "4" in the second position), 354 (for the triplet with a "3" in the second position), 432,456,475,491 (for the triplets with a "2" in the second position) and finally 282 for the triplet with a "1" in the second position.

Any help would be highly appreciated. Thanks.


Solution

  • Remove the col parameter from the sortByColumn method since it is not really a parameter and change the method in this way:

    // Function to sort by column 
    public static void sortbyColumn(int arr[][]) {
        // Using built-in sort function Arrays.sort 
        Arrays.sort(arr, new Comparator<int[]>() {
            @Override
            // Compare values according to columns 
            public int compare(final int[] entry1, final int[] entry2) {
                if (entry1[1] < entry2[1])
                    return 1;
                else if (entry1[1] > entry2[1])
                    return -1;
    
                return -1 * Integer.valueOf(entry2[2])
                        .compareTo(Integer.valueOf(entry1[2]));
            }
        }); // End of function call sort(). 
    }
    

    Of course change the call in main to sortbyColumn(matrix);

    Explanation:

    We need to compare by the third column only in cases of equality by the second column (which means thet first comparison numeric result is equal to 0). In that case we compare in reverse order, which we can obtain by multiplying the comparison result by -1.

    Result:

    8 5 134 
    7 5 171 
    4 5 293 
    3 4 191 
    9 3 354 
    0 2 432 
    2 2 456 
    5 2 475 
    6 2 491 
    1 1 282