1

I have 2 arrays of data in Java. Based on the order of first array I have to sort the next array. E.g -

String[] Array1 = {"EUROPE","MIDDLEEAST","OTHERs","AUSTRALIA"};
String[] Array2 = {"MIDDLEEAST","EUROPE","AUSTRALIA","OTHERs","ASIA","EUROPE"};

My output should look like:

{"EUROPE","EUROPE","MIDDLEEAST","OTHERs","AUSTRALIA","ASIA"}

What is the best way to do it?

9
  • 1
    Everything made sense until you got to your example. How does sorting Array1 end up with Array2 sorted that way? Commented Jan 19, 2012 at 7:48
  • They are 2 different arrays. resultArray is the sorted one not Array2.Elements in both Array1 and Array2 are different. Commented Jan 19, 2012 at 7:50
  • 1
    It seems you just use the first character to determine the order??? and that order depends on array1.... this is not sorting, this is more like mapping. Commented Jan 19, 2012 at 7:50
  • is it a brainteaser? o-O Commented Jan 19, 2012 at 7:51
  • To sort Array1 of your example, I just need to swap the first two elements. But your resultArray is obtained from Array2 by swapping the first and third elements. What's the logic you're trying to accomplish? Commented Jan 19, 2012 at 7:53

5 Answers 5

4

To sort you need to define a sorting order so given element A and B, you can determine easily if A should go before or after B in the sorted list.

This concept is formalized with the concept of a Comparator in Java.

In this case the sorting order is defined by the order of the elements in a list. The simplest approach is given A and B to find each of them in the original list, note the index found, and compare the indexes to find out which one goes first.

Depending on the size of your data this might be too slow. You can then create a HashMap<String,Long> which holds the index of a given string in Array1. Here it would hold "DEF"->0, "ABC"->1, "XYZ"->2.

Sign up to request clarification or add additional context in comments.

6 Comments

Allocating a hashtable with all the array1 elements' locations seems inefficient from a space point of view. Also, it would fail if array1 contains duplicate elements.
@DilumRanatunga if array1 contains duplicate elements how would you define the sorting order? Regarding inefficiency, how else would you speed up the process?
In sorting, there is a term 'stable'. A stable sort would not swap the order of elements that are equivalent. Some sort algorithms exhibit this behavior and others don't. Note that Arrays.sort(...) is stable.
@DilumRanatunga Space is frequently traded off for speed. Especially in the Java world. And you did not suggest any speed improvement yourself - comparing strings is much slower than you appear to think.
@DilumRanatunga having a Comparator doing indexed string comparisons with auto-unboxing for every compare seems inefficient from a performance point of view.
|
0

May be this:

1) Sort both of them.

2) Create blank result table

3) Take first elem from sorted Array2 and put it to result table with the original index of the first elem on sorted Array1

3) Repeat the step 3 on the second element and so on.

The computational complexity would be like sorting method used: O(nlogn) for quicksort

Comments

0

You can definitely do this in O(n log n). But the best approach depends on what is more important: quick, clean code or not allocating extra memory.

If you don't care about using extra memory, you can allocate a separate array, where each element is a pair:

public class Pair implements Comparable {
  ...
}

Then you would sort the array of pairs using Arrays.sort(Object[]).

If you don't want to allocate quite so much space, you can use an auxiliary array that contains the indexes in Integer form:

final String[] array1 = ...;
final String[] array2 = ...;

assert array1.length == array2.length;

Comparator<Integer> c = new Comparator<Integer> {
  int compare(Integer a, Integer b) {
    return array1[a].compareTo(array1[b]);
  }
};

Integer[] aux = new Integer[array1.length];
for (int i = 0; i < aux.length; ++i) { aux[i] = i; }
Arrays.sort(aux, c);

String[] result = new String[array1.length];
for (int i = 0; i < aux.length; ++i) {
  result[i] = array2[aux[i]];
}

If you are trying to do the entire thing in-place and not allocate additional memory, then you will need to implement one of the n-log-n sort algorithms yourself...

Comments

0

There are (at least) two ways to sort one array and reorder a second array so corresponding elements still match. Both require constructing a third array and writing a custom comparison function.

Method 1

Define a custom object that contains one element of each array. (In your case, it might be a two-element String array.) Write a comparator (or implement Comparable) for the custom object that simply compares the elements from the first array. Build an array of the custom objects from the two input arrays, sort the third array, and then extract the results.

This is the method most commonly recommended for this problem.

Method 2

Construct an array of Integer indexes initialized to 0, 1, 2, ..., n-1 (where n == Array1.length). Sort the index array using a comparator that compares indexes by comparing the Array1 elements that they index.

The second method will be faster and will not require as much object construction.

Comments

0

Two other ideas:

  1. Could these values be an enum rather than a set of strings? The natural order of an enum is the order of declaration, so Arrays.sort() would just work.

  2. Helper code exists in Guava's Ordering.explicitOrder(List):

    String[] explicitOrder = {"EUROPE", "MIDDLEEAST", "OTHERs", "AUSTRALIA"};
    String[] toSort = ...
    
    Comparator<String> comparator = Ordering.explicit(Arrays.asList(explicitOrder));
    String[] sorted = Arrays.sort(toSort, comparator); 
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.