Sorting a 2D array of integers by values in columns

269 views Asked by At

I am trying to sort a 2D array of integers in Java in increasing order according to the values of every column.

Let me explain my objective with the following example:

This is my array:

int[][] array = new int[][]{
        {7, 3, 9},
        {9, 1, 3},
        {5, 8, 8}};

Here is the expected array:

int[][] newArray = new int[][]{
        {5, 1, 3},
        {7, 3, 8},
        {9, 8, 9}};

As can see in the example, every values on newArray are the same as array but now ordered in each column in increasing order.

Almost all the questions in the forum are focused on how to sort a 2D array according to the values of a row or column, but I need this for every column.

2

There are 2 answers

0
WJS On BEST ANSWER

You could do it like this.

  • The static Lambda does the sort by column. I did this to get around the effective final restriction on modifying local variables inside of streams, in this case the column.
  • The sortByColumn method calls this lambda for each number of columns.
  • This only supports rectangular matrices.
static BiFunction<int[][], Integer, int[][]> sortColumn = (arr,c) -> {
     int[] temp = IntStream.range(0, arr.length)
        .map(i -> arr[i][c]).sorted().toArray();
     for (int i = 0; i < arr.length; i++) {
         arr[i][c] = temp[i];
     }
     return arr;
};
    
public static void main(String[] args) {
    int[][] array =
            new int[][] { { 7, 3, 9 }, { 9, 1, 3 }, { 5, 8, 8 } };
    
    array = sortByColumn(array);
    System.out.println(Arrays.deepToString(array)); 
}

Prints

[[5, 1, 3], [7, 3, 8], [9, 8, 9]]
    
public static int[][] sortByColumn(int[][] arr) {
     for (int col = 0; col < arr[0].length; col++) {
         arr = sortColumn.apply(arr,col);
     }
     return arr;
}
0
AudioBubble On

To sort the elements of the columns of a matrix, you can sort the elements of the rows of the transposed matrix and then transpose it back:

int m = 3;
int n = 4;
int[][] arr = {
        {7, 3, 9, 2},
        {9, 1, 3, 1},
        {5, 8, 8, 7}};
// sorting transposed matrix
int[][] arr2 = IntStream
        // iterate over the indices
        // of the rows of the matrix
        .range(0, n)
        .mapToObj(i -> IntStream
                // iterate over the
                // indices of the columns
                .range(0, m)
                .map(j -> arr[j][i])
                .sorted()
                .toArray())
        .toArray(int[][]::new);
// transposing sorted matrix
int[][] arr3 = IntStream
        // iterate over the indices of the
        // rows of the transposed matrix
        .range(0, m)
        .mapToObj(i -> IntStream
                // iterate over the
                // indices of the columns
                .range(0, n)
                .map(j -> arr2[j][i])
                .toArray())
        .toArray(int[][]::new);
// output
Arrays.stream(arr3).map(Arrays::toString).forEach(System.out::println);
[5, 1, 3, 1]
[7, 3, 8, 2]
[9, 8, 9, 7]

See also: Sorting 2D array of integers by column