Mivakes
Mivakes

Reputation: 3

Sort half of a String ArrayList based on a substring of each string

I have a String ArrayList of sizes, for example

[12, 10L, 10, 10R, 10S, 10L]

The output should be

[10S, 10R, 10L, 10, 12]

So basically sizes must be first sorted by number - (1,2,3,4,5 ... etc) then by letters.

I managed to get the numbers to sort, so my current output for the input above is

10L, 10, 10R, 10S, 10L, 12

if a letter is missing, then it is the largest (see output above - 10 is after 10L - 10S < 10R < 10L < 10 < 12. )

How should i code a comparator that allows me to do this?

Consider an input array, sizes. This array contains product sizes in the format AB, where:

A is a mandatory integer B is an optional character in [S,R,L] Sizes must first be ordered from smallest to largest by A, and then by B in the order S

Upvotes: 0

Views: 449

Answers (2)

Kaus2b
Kaus2b

Reputation: 845

Try this if it works for your testcases. We can always refine it if needed. (Added a helper method)

List<String> list = new ArrayList<>(Arrays.asList("12","10L","10","10R","10S","10L","14L","14","8","12S"));
List<String> orderArray = new ArrayList<>(Arrays.asList("S", "R", "L"));

List<String> sortedList = list.stream()
            .sorted(Comparator.comparing(str -> Integer.parseInt(((String)str).replaceAll("[A-Z]*","")))
                    .thenComparing(str -> getAnInt(orderArray, (String) str)))
            .distinct()
            .collect(Collectors.toList());

System.out.println(sortedList);

private int getAnInt(List<String> orderArray, String str) {
    int i = orderArray.indexOf(str.substring(str.length() - 1));
    if (i == -1) return Integer.MAX_VALUE;
    return i;
}

Output: [8, 10S, 10R, 10L, 10, 12S, 12, 14L, 14]

if you don't want to use streams:

List<String> list = new ArrayList<>(Arrays.asList("12","10L","10","10R","10S","10L","14L","14","8","12S"));
List<String> orderArray = new ArrayList<>(Arrays.asList("S", "R", "L"));

list.sort(new Comparator<String>() {
        @Override
        public int compare(String lhs, String rhs) {
            int lInt = Integer.parseInt(lhs.replaceAll("[A-Z]*", ""));
            int rInt = Integer.parseInt(rhs.replaceAll("[A-Z]*", ""));
            if (lInt != rInt) {
               return lInt - rInt;
            } else {
                return getAnInt(orderArray, lhs) - getAnInt(orderArray, rhs);
            }
        }
    });

System.out.println(list);

Upvotes: 1

Danyal Sandeelo
Danyal Sandeelo

Reputation: 12391

I assume finalList list has the sort data.

10L, 10, 10R, 10S, 10L, 12

Use regex to match the integer, merge the list of alphanumerics and numbers.

On your sorted list, run this

List<String> numberList= new ArrayList<String>(); // store number list
List<String> sizeList= new ArrayList<String>(); // store alphanumerics
for(String value: finalList){

  if(!value.matches("[0-9]+")){  // if contains characters
     sizeList.add(value);
   }
   else{
        numberList.add(value);
  }
}

sizeList.addAll(numberList); 

sizeList has what you need

Upvotes: 0

Related Questions