简体   繁体   中英

Sorting 2D Array but keeping column elements together

I have a 2D array with 2 rows and n columns.

I am trying to sort the array using the built in Arrays.sort method, but I am struggling with the comparator. I want to sort the 2D array by the first row, so that the 2nd row elements will remain with the original elements they were aligned with ie. keep the columns together.

For example original array:

int[] unsortedArray = new int[][]{ { 6, 3, 1, 2, 3, 0}, { 2, 1, 6, 6, 2, 4},

sorted array:

int[] unsortedArray = new int[][]{ { 0, 1, 2, 3, 3, 6}, { 4, 6, 6, 1, 2, 2},

What is the best way to go about doing this? Cheers.

Try the following:

Disclaimer: Not tested :)

myarray = new int[10][2];

// populate the array here

Arrays.sort(myarray, new Comparator<int[]>() {
    public int compare(int[] a, int[] b) {
        if (a[0] > b[0])
            return 1;
        else if (a[0] < b[0])
            return -1;
        else {
            return 0;
        }
    }
};

You will have to write a custom sort. Look into Comparable and Comparator .

Something along the lines of:

public class MyComparator implements Comparator<T[]> {
    int columnToSortOn;
    public MyComparator(int columnToSortOn) {
        this.columnToSortOn = columnToSortOn;
    }
    @Override
    public int compare(T[] array1, T[] array2) {
        return array1[columnToSortOn].compareTo(array2[columnToSortOn]);
    }
}

Here is an alternative way of keeping your columns aligned. This uses a simple class to hold both column elements.

class TwoInts  {
   public final int aElement;
   public final int bElement;
   public TwoInts(int a_element, int b_element)  {
      aElement = a_element;
      bElement = b_element;
   }
}

One by one, each column (from sub-array one and two) are placed in this object, and immediately put into a Map<Integer,List<TwoInts>> . The key is the element from intArrayArray[0] , and the value is a list of TwoInts , because there may be (and in your example code, are) duplicate values in intArrayArray[0] .

You then iterate through the map's key-set, and replace them into the array.

Full code:

  import  java.util.ArrayList;
  import  java.util.Arrays;
  import  java.util.Iterator;
  import  java.util.List;
  import  java.util.Map;
  import  java.util.TreeMap;
/**
   <P>{@code java SortOneArrayKeepSecondArrayElementsAligned}</P>
 **/
public class SortOneArrayKeepSecondArrayElementsAligned  {
   public static final void main(String[] ignored)  {
      int[][] intArrayArray = new int[][]{
        { 6, 3, 1, 2, 3, 0},
        { 2, 1, 6, 6, 2, 4}};
      output2DArray("Unsorted", intArrayArray);

      Map<Integer,List<TwoInts>> twoIntMap = new TreeMap<Integer,List<TwoInts>>();
      for(int i = 0; i < intArrayArray[0].length; i++)  {
         int intIn0 = intArrayArray[0][i];
         if(!twoIntMap.containsKey(intIn0))  {
            List<TwoInts> twoIntList = new ArrayList<TwoInts>(intArrayArray.length);
            twoIntList.add(new TwoInts(intArrayArray[0][i], intArrayArray[1][i]));
               twoIntMap.put(intIn0, twoIntList);
         }  else  {
            twoIntMap.get(intIn0).add(new TwoInts(intArrayArray[0][i], intArrayArray[1][i]));
         }
      }

      int idx = 0;
      Iterator<Integer> itr2i = twoIntMap.keySet().iterator();
      while(itr2i.hasNext())  {
         List<TwoInts> twoIntList = twoIntMap.get(itr2i.next());
         for(TwoInts twoi : twoIntList)  {
            intArrayArray[0][idx] = twoi.aElement;
            intArrayArray[1][idx++] = twoi.bElement;
         }
      }

      output2DArray("Sorted", intArrayArray);
   }
   private static final void output2DArray(String description, int[][] twoD_array)  {
      System.out.println(description + ":");
      System.out.println("0: " + Arrays.toString(twoD_array[0]));
      System.out.println("1: " + Arrays.toString(twoD_array[1]));
      System.out.println();
   }

}
class TwoInts  {
   public final int aElement;
   public final int bElement;
   public TwoInts(int a_element, int b_element)  {
      aElement = a_element;
      bElement = b_element;
   }
}

Output:

[C:\java_code\]java SortOneArrayKeepSecondArrayElementsAligned
Unsorted:
0: [6, 3, 1, 2, 3, 0]
1: [2, 1, 6, 6, 2, 4]

Sorted:
0: [0, 1, 2, 3, 3, 6]
1: [4, 6, 6, 1, 2, 2]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM