3

If the title isn't clear, let me give you an example:

I've got an array sorted by first column - date and I need to sort it once again in order of appearance of value in column name

data[100][4]

date | name | text | type
-----+------+------+------
2222 | z    | wwww | 2
2221 | z    | qqqq | 1
2220 | c    | dasa | 2
2219 | b    | dsad | 1
2218 | z    | dfsa | 2
2217 | c    | dasd | 1

And here's the sorted array:

order[100][4]

date | name | text | type
-----+------+------+------
2222 | z    | wwww | 2
2221 | z    | qqqq | 1
2218 | z    | dfsa | 2
2220 | c    | dasa | 2
2217 | c    | dasd | 1
2219 | b    | dsad | 1

I thought of merging those data into one string and inserting some symbol between columns to retrieve it back in the future, adding to ArrayList and then retrieving by name. I've added data[i][1] to HashMap to determine number of unique values, so I could know the number of loop cycles. And there comes the order of name values which puzzles me because HashMap doesn't maintain order.

Does anyone know how it can be sorted without all that trouble?

2
  • If you want order, LinkedHashMap preserves insertion order. Commented Jun 23, 2015 at 21:56
  • Use Java Collections and Comparators. Commented Jun 23, 2015 at 22:17

3 Answers 3

2

Have an object representing a data entry with a date, name, text, and type, and have it implement the Comparable interface. The Comparable interface effectively allows inequality operations to be performed on the objects, and is what the Java API uses to do any sort of comparison of objects (which is used for sorting). Then to sort the data according to the given field, include a static variable in the data object class that represents which field to sort on.

class Data implements Comparable<Data>
{
    int date;     // field 1
    String name;  // field 2
    String text;  // field 3
    int type;     // field 4

    static int sortField;
    static final int DATE = 1;
    static final int NAME = 2;
    static final int TEXT = 3;
    static final int TYPE = 4;

    // put constructor here

    //compareTo function for sorting
    public int compareTo(Data other)
    {
        if (sortField == DATE)
        {
            if (date < other.date)    return -1;
            if (date > other.date)    return 1;
            else                      return 0;
        }
        if (sortField == NAME)
        {
            return name.compareTo(other.name);
        }
        if (sortField == TEXT)
        {
            return text.compareTo(other.text);
        }
        else
        {
            if (type < other.type)    return -1;
            if (type > other.type)    return 1;
            else                      return 0;
        }
    }
}

Then all you have to do is put the objects into an ArrayList and sort them

ArrayList<Data> list = new ArrayList<Data>();

//put Data objects into list here

//to sort
Data.sortField = Data.DATE;   //sort by date - change as needed
Collections.sort(list);
Sign up to request clarification or add additional context in comments.

6 Comments

but in this it will be single dimensional array. question says multidimensional array.
@RamanShrivastava The Data object in the List contains the multiple data points that made the array multidimensional in the first place.
got it. but what if my multi-dim array of of some other type.. or i want to introduce some columns in it. How this will handle?
You could make the class dynamic-ish. Instead of a variable for each field, you could have an ArrayList<Object>, storing each field in some arbitrary order in the list, then make the compareTo() just return list.get(sortField).compareTo(other.list.get(sortField)). sortField would be the index of the field in the ArrayList.
Your code works and sorts my data but in alphabetical order, and I specified the order has to be by appearance. Like: z, b, c, z, c, z, b is sorted z, z, z, b, b, c, c
|
2

I've used @Aderis idea of creating a class but sorting method is slightly different. A code to initialise an array was posted here but someone deleted it. Anyway, I also used it.

String[][] myArr = { { "2222", "b", "dfsa", "2" },
                { "2221", "z", "wwww", "2" }, { "2220", "c", "qqqq", "1" },
                { "2219", "z", "dasa", "2" }, { "2218", "b", "dsad", "1" } };

HashMap<String,String> hashData = new HashMap<>();

for (int i = 0; i < myArr.length; i++) hashData.put(myArr[i][1],myArr[i][1]);
int unique_entries = hashData.size();

ArrayList<Data> list = new ArrayList<Data>();
ArrayList<Data> list_sorted = new ArrayList<Data>();

for (int i = 0; i < myArr.length; i++){
    Data temp = new Data(myArr[i][0],myArr[i][1],myArr[i][2],Integer.parseInt(myArr[i][3]));
    list.add(temp);
}

for (int k = 0; k < unique_entries; k++){
    boolean flag = true;
    ArrayList<Integer> elements = new ArrayList<>();
    int list_elements = list.size(); 
    for (int i = 0; i < list_elements; i++){
        if (flag){
            list_sorted.add(list.get(i));
            elements.add(i);
            flag = false;
            continue;
        }
        int list_sorted_elements = list_sorted.size(); 
        for (int j = 0; j < list_sorted_elements; j++){
            if (list_sorted.get(j).name.contains(list.get(i).name)){
                list_sorted.add(list.get(i));
                elements.add(i);
                break;
            }
        }
    }
    for (int i = 0; i < elements.size(); i++){ 
        int temp = elements.get(i);
        if (i != 0) temp = temp - i;
        list.remove(temp);
    }
}

As you can see, to establish the number of unique elements I add them to HashMap and check its size. I fill an ArrayList with objects of my data and add sorted data to another ArrayList, then I delete those data from unsorted List and begin to sort the rest. There are as many cycles as unique names.

I don't believe this is an optimal way. But it's the only way I know. If anyone knows faster way I'll accept their post.

Comments

0

Convert this 2d array into a HashMap. Object part will hold that particular array element.

Get keyset .. convert keyset into list.. sort this list.. iterate over list and get their respective array element from map.

e.g code:

        String[][] myArr = new String[4][3];
        for (int i=0; i<myArr.length; i++) {
            myArr[i][0] = (i+1)+"1";
            myArr[i][1] = (i+1)+"2";
            myArr[i][2] = (i+1)+"3";
        }

        Map<String, Object> map = new HashMap<String, Object>();
        for (int i=myArr.length-1; i>=0; i--) {
            map.put(myArr[i][0], myArr[i]);
        }

        List<String> keyList = new ArrayList<String>(map.keySet());

        Collections.sort(keyList);

        String[][] myNewArray = new String[4][3];
        int a =0;
        for (String s : keyList) {
            myNewArray[a++] = ((String[])map.get(s));
        }

I am using String, in your case it is date. Even if it is something else, you can use comparable or compactor to sort that keylist.

Use your sort key as the key in map.

1 Comment

I guess you didn't understand the question. Data in the array is already sorted by date and needs to be sorted by name in order of appearance

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.