0

I think many people have come across this problem, You have a 2D array consisting of a String conponent and an Interger. ex.

    `String[][] data = {{"Name1","5"}, {"Name2","10"},{"Name3","1"}, {"Name4","3"}};`

Now you want to sort that 2D array by the integer (in this case the players score), however you want the matching name to be moved along with the players score. This is what i've got, but the result is far away from what it is suppose to be.

    private void sort(){
    boolean sort;
    int current, next;
    do{
            sort = true;
            for (int i = 0; i < data.length - 1; i++){
                if (data[i][1] !=null && data[i+1][1] != null){
                    current = Integer.parseInt(data[i][1]);
                    next = Integer.parseInt(data[i+1][1]);
                        if(current > next){
                                String temp = "";
                                data[i][1] = Integer.toString(next); 
                                data[i+1][1] = Integer.toString(current);
                                data[i][0] = temp;
                                data[i][0] = data[i+1][1];
                                data[i+1][0] = temp;       
                                sort = false;
                        }
                }

            }

    }while(!sort);
}

If you ask why people would use a common 2D array, it is because in JFRAME, a JTable needs an 2D array for the data.

1
  • See my answer: while not generic enough, it can give hindsights. In essence, your array elements need to be able to compare to one another? Commented Jan 3, 2013 at 2:04

2 Answers 2

4

You can write a special Comparator, wich can compare e.g. {"Name1","5"} and {"Name2","10"} But I recomment to change your data structure.

I would create a type caonatining name and int

class NameNum{
   String name;
   int number;
}

and store them in a 1D Array

NameNum[] data 

Implement a compare method and than simply use Arrays.sort(..) to sort the array.

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

16 Comments

While your are at it, why not make the NameNum class implement Comparable of itself? It would allow to use some very convenient collections primitives ;)
Well, implementing Comparable in this case looks like a good idea since you can use SortedSet to full effect, see my answer.
Instead of creating a new class you could also maintain a Map that maps the "nameN" strings to ints (or int strings w/e) and work with that. That seems more fitting in my opinion.
@A.R.S. that would be a solution, but it does not account for the fact that two players with a different name can have the same score
A Map or a Set can only be used, if every Key / Entry will be unique, what we do not know from rge description given in the question.
|
0

First of all: your array elements do not consist of a string and an integer since in:

{ "Name1", "5" }

"5" is not an Integer but a String.

Provided that you do not care about equality, the solution here is to create a wrapper object over this tuple, make it implement Comparable of itself and use a SortedSet. You will have to reverse it for display, and fortunately the JDK also has builtin methods for that.

Sample code:

private static final String[][] data = {
    { "Name1", "5" },
    { "Name2", "10" },
    { "Name3", "1" },
    { "Name4", "3" }
};

private static final class Score
    implements Comparable<Score>
{
    private final String name;
    private final int score;

    private Score(final String name, final String scoreAsString)
    {
        this.name = name;
        // NOTE: this can throw an (unchecked) NumberFormatException,
        // but this code assumes that it never does
        score = Integer.parseInt(scoreAsString);
    }

    @Override
    public int compareTo(final Score o)
    {
        final int ret = score - o.score;
        return ret != 0 ? ret : name.compareTo(o.name);
    }

    // Print results nicely ;)
    @Override
    public String toString()
    {
        return "Name: " + name + ", score: " + score;
    }
}

public static void main(final String... args)
{
    final SortedSet<Score> set = new TreeSet<Score>();
    Score score;

    for (final String[] raw: data) {
        score = new Score(raw[0], raw[1]);
        set.add(score);
    }

    // Build a List from that Set...
    final List<Score> scoreList = new ArrayList<Score>(set);

    // Reverse it...
    Collections.reverse(scoreList);

    // Print results
    for (final Score s: scoreList)
        System.out.println(s);
}

Copy/paste the above code in a class, run it: you will see that it does what is intended.

IMPORTANT NOTE: yes, this custom class does not override equals()/hashCode(); this is not an oversight: as only comparison is required here (since a SortedSet is used), there was no reason for implementing them at all.

2 Comments

since a player could play the game multiple times, he won't be unique.
Well, the code will work equally well in that event, the comparison will just return 0 ;) Edited...

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.