Victor Kusters
Victor Kusters

Reputation: 21

Sorting multidimensional string array by first name and last name

A Java class assignment I have is asking me to sort a multidimensional string array. It also requires input on whether you want to sort by the first name or by the last name. I don't understand the wording of the question that well, namely on primary sort and the bolded parts, so I'll post it here.

Part A: Multi-Dimension Arrays

Write a program to sort a two-dimensional array using the following header:

Public static void sort string ( nameSort [][]  )

The method should perform a primary sort on rows and then on columns.

Use the following data to test your program:

{  
 {“Bill”,”Jones”}, 
 {“Janet”,”Kline”},
 {“George”,”Bailey”}, 
 {“Ellan”,”Sanches”}, 
 {“Tom”,”Nguyen”}, 
 {“William”,”Walters}, 
 {“Author”,”James”}, 
 {“Henry”,”Daniels”}, 
 {“Mike”,”Franklin”}, 
 {“Julie”,”Andrews"}
}

Your program should ask if you want the array sorted by the First Names or by the Last sName.

Rows in the array will contain First names. Columns in the sortArray will contain Last names.

Upvotes: 1

Views: 1784

Answers (4)

AxelH
AxelH

Reputation: 14572

First, let's define an enumeration to the order we want to manage. This will hold the indexes that we want to uses for the sort.

private enum SortType { 
    FIRSTNAME(1, 0), 
    LASTNAME(0, 1);

    int sortIndex;
    int sortIndex2;

    private SortType(int sortIndex, int sortIndex2){
        this.sortIndex = sortIndex;
        this.sortIndex2 = sortIndex2;
    }
}

Note : This could be an array instead, allowing us to define an unlimited amount of "fallback" column.

Then, all we need to do is create the comparator to sort based on those two indexes :

private static void sort(String[][] array, SortType type){
    Arrays.sort(array, (a1, a2) -> {
        int r = a1[type.sortIndex].compareTo(a2[type.sortIndex]);
        return r == 0 ? a1[type.sortIndex2].compareTo(a2[type.sortIndex2]) : r; 
    });
}

Let create the method to get the input from the user :

private static SortType getType(Scanner sc){
    boolean again = false;
    String input;

    System.out.println("Sort option.\n1 : Firstname\n2: Lastname");
    SortType type = null;

    //Get a valid input for the type.
    do{
        input = sc.nextLine().trim();
        if(input.equals("1")){
            type = SortType.FIRSTNAME;
            again = false;
        } else if(input.equals("2")){
            type = SortType.LASTNAME;
            again = false;
        } else {
            System.out.println("Bad input, try again");
            again = true;
        }
    }while(again);

    return type;
}

And let's run it :

public static void main(String... args) {
    String[][] array = { { "Bill", "Jones" }, { "Janet", "Kline" }, { "George", "Bailey" }, { "Ellan", "Sanches" }, { "Tom", "Nguyen" },
            { "William", "Walters" }, { "Author", "James" }, { "Henry", "Daniels" }, { "Mike", "Franklin" }, { "Julie", "Andrews" } };

    System.out.println(Arrays.deepToString(array));

    Scanner sc = new Scanner(System.in);
    SortType type = getType(sc);
    sc.close();

    //Sort the array
    sort(array, type);

    //Print the array
    System.out.println(Arrays.deepToString(array)); 
}

[[Bill, Jones], [Janet, Kline], [George, Bailey], [Ellan, Sanches], [Tom, Nguyen], [William, Walters], [Author, James], [Henry, Daniels], [Mike, Franklin], [Julie, Andrews]]
Sort option.
1 : Firstname
2: Lastname
sa
Bad input, try again
5
Bad input, try again
2
[[Author, James], [Bill, Jones], [Ellan, Sanches], [George, Bailey], [Henry, Daniels], [Janet, Kline], [Julie, Andrews], [Mike, Franklin], [Tom, Nguyen], [William, Walters]]

Upvotes: 0

KayV
KayV

Reputation: 13845

Here is the minimalistic code using Java 8:

    public static void sort2DArray(boolean sortByFirstName) {
        System.out.println("***** Sorting 2D Array *****");
        String[][] arr = {{"Bill","Jones"}, 
                            {"Janet","Kline"},
                            {"George","Bailey"}, 
                            {"Ellan","Sanches"}, 
                            {"Tom","Nguyen"}};
        List<String> l =  convertToList(arr);
        System.out.println("List = "+l.toString());
        if(sortByFirstName)
            Collections.sort(l, (s1, s2) -> s1.split(" ")[0].compareTo(s2.split(" ")[0]));
        else
            Collections.sort(l, (s1, s2) -> s1.split(" ")[1].compareTo(s2.split(" ")[1]));
        System.out.println("Sorted List = "+l.toString());


    }

    public static List<String> convertToList(String[][] arr){
        List<String> l8 = Arrays.asList(arr).stream().map(a -> a[0] + " "+ a[1]).collect(Collectors.toList());
        return l8;
    }

Explanation: 1. First convert the 2D array into a list of string.

  1. Then sort the list based on the comparator.

Upvotes: 0

Tiago Redaelli
Tiago Redaelli

Reputation: 620

Sorts the names through selection sort, use the flag to determine if it should be ordered by first or last name.

public static void main(String[] args) {
   String[][] names = 
   {{"Bill","Jones"}, 
    {"Janet","Kline"},
    {"George","Bailey"}, 
    {"Ellan","Sanches"}, 
    {"Tom","Nguyen"}, 
    {"William","Walters"}, 
    {"Author","James"}, 
    {"Henry","Daniels"}, 
    {"Mike","Franklin"}, 
    {"Julie","Andrews"}};
   print(names);
   sortNames(names, true);
    System.out.println("-----");
    print(names);
}

public static void print(String[][] name) {
    int n = name.length;
    for (int i = 0; i < n; i++) {
        System.out.println(name[i][0] + " " + name[i][1]);
    }
}

private static void swap(String[][] name, int i, int j) {
    String firstName = name[i][0];
    String lastName = name[i][1];
    name[i][0] = name[j][0];
    name[j][0] = firstName;
    name[i][1] = name[j][1];
    name[j][1] = lastName;
}

public static void sortNames(String[][] name, boolean orderByFirst) {
    int n = name.length;      
    for (int i = 0; i < n - 1; i++) {
        int f = i;
        for (int j = i; j < n; j++) {
            // Sort on first name
            if (orderByFirst) {
                int compFirstName = name[f][0].compareTo(name[j][0]);
                if (compFirstName > 0) {
                    f = j;
                }
                // Same fist name, sort on last name
                else if (compFirstName == 0 && name[f][1].compareTo(name[j][1]) > 0) {
                    f = j;
                }
            } else {
               // sort by last name instead
               int comptLastName = name[f][1].compareTo(name[j][1]);
                if (comptLastName > 0) {
                    f = j;
                }
                // Same last name, sort on first name
                else if (comptLastName == 0 && name[f][0].compareTo(name[j][0]) > 0) {
                    f = j;
                }
            }
        }
        swap(name, i, f);
    }
}

Output (sort on first name):

Author James
Bill Jones
Ellan Sanches
George Bailey
Henry Daniels
Janet Kline
Julie Andrews
Mike Franklin
Tom Nguyen
William Walters

Output (sort by last name):

Julie Andrews
George Bailey
Henry Daniels
Mike Franklin
Author James
Bill Jones
Janet Kline
Tom Nguyen
Ellan Sanches
William Walters

Upvotes: 0

cyqsimon
cyqsimon

Reputation: 3715

From my understanding of the question, the question is simply asking you to write a program that sorts the array on either first name or last name, with both fields conveniently provided separately in the form of an array.

The wording of the question is strange though. I think by "row and column" they actually meant "first and second element of the array". I find no better interpretation.

The question did not explicitly state whether using convenient library methods such as Arrays.sort() is allowed. In practice, Arrays.sort() is what I would use due to its convenience. If you need to explicitly write the sort code, just tell me and I can write that too.

P.S. In setting the comparator I used a lambda statement, which is a Java 8+ feature. Use anonymous class instead if using Java 7.

Code:

    // Test array.
    String[][] test = { { "Bill", "Jones" }, { "Janet", "Kline" }, { "George", "Bailey" },
            { "Ellan", "Sanches" }, { "Tom", "Nguyen" }, { "William", "Walters" }, { "Author", "James" },
            { "Henry", "Daniels" }, { "Mike", "Franklin" }, { "Julie", "Andrews" } };

    // Print unsorted array.
    System.out.println("Unsorted array:");
    for (String[] strArr : test)
    {
        System.out.println(strArr[0] + " " + strArr[1]);
    }

    Scanner input = new Scanner(System.in);
    Comparator<String[]> c;

    // Loop until correct input.
    while (true)
    {
        System.out.println("Sort by first name or last name?");
        System.out.println("Type f for first name, or l for last name.");
        String in = input.nextLine();
        if (in.equals("f"))
        {
            // Set comparator to compare by first name then last name.
            c = (a1, a2) ->
            {
                int result = a1[0].compareTo(a2[0]);
                if (result == 0)
                {
                    result = a1[1].compareTo(a2[1]);
                }
                return result;
            };
            break;
        }
        if (in.equals("l"))
        {
            // Set comparator to compare by last name then first name.
            c = (a1, a2) ->
            {
                int result = a1[1].compareTo(a2[1]);
                if (result == 0)
                {
                    result = a1[0].compareTo(a2[0]);
                }
                return result;
            };
            break;
        }
        System.out.println("Illegal input. Please try again.");
    }

    // Sort.
    Arrays.sort(test, c);

    // Print sorted array.
    System.out.println("Sort complete. Sorted array:");
    for (String[] strArr : test)
    {
        System.out.println(strArr[0] + " " + strArr[1]);
    }

Upvotes: 1

Related Questions