Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I sort a list of clothing sizes (e.g. 4XL, S, 2XL)?

Tags:

java

java-8

I need your help follow query. Given the following List:

["2XL", "3XL", "4XL", "5XL", "6XL", "L", "M", "S", "XL"]

How do I sort it so that it is in this order?

["S", "M", "L", "XL", "2XL", "3XL", "4XL", "5XL", "6XL"]

Note that every size is not always present.

like image 552
Nidamanuri Venkateswarlu Avatar asked Jan 17 '18 10:01

Nidamanuri Venkateswarlu


People also ask

What is my size in Japan?

For each U.S. half-size, the Japanese size goes up by one. For example, a U.S. size 14.5 is a Japanese size 37, and a U.S. size 15 is a Japanese size 38. Similarly, Japanese collar sizes increase by 1 for every 0.5 increase in Western collar sizes.

What is my size in China?

According to SizeChart.com, sizes in China are typically one size smaller than they are in the United States. That means that when you shop a size large, you're actually asking for a medium by U.S. standards. To put it simply, always size up your clothing if you're shopping from China.

Are Japanese sizes smaller?

Japanese clothes sizes. If you've never been to Japan and you go clothes shopping, you're in for a surprise. Japanese clothes sizes start much smaller than they do in most other countries. If we look at the raw numbers, it's easy to see how Japanese clothes sizes are smaller than those in Europe and the US.


2 Answers

A general approach would focus on the pattern behind the size strings rather than just accom­modating the sample input. You have a fundamental direction denoted by S, M, or L and optional modifiers before it (unless M) altering the magnitude.

static Pattern SIZE_PATTERN=Pattern.compile("((\\d+)?X)?[LS]|M", Pattern.CASE_INSENSITIVE);
static int numerical(String size) {
    Matcher m = SIZE_PATTERN.matcher(size);
    if(!m.matches()) throw new IllegalArgumentException(size);
    char c = size.charAt(m.end()-1);
    int n = c == 'S'? -1: c == 'L'? 1: 0;
    if(m.start(1)>=0) n *= 2;
    if(m.start(2)>=0) n *= Integer.parseInt(m.group(2));
    return n;
}

Then, you can sort a list of sizes like

List<String> sizes = Arrays.asList("2XL", "5XL", "M", "S", "6XL", "XS", "3XS", "L", "XL");
sizes.sort(Comparator.comparing(Q48298432::numerical));
System.out.print(sizes.toString());

where Q48298432 should be replaced with the name of the class containing the numerical method.

like image 186
Holger Avatar answered Oct 23 '22 10:10

Holger


Build a comparator which does a lookup on your desired order:

Comparator<String> sizeOrder = Comparator.comparingInt(desiredOrder::indexOf);

where

desiredOrder = Arrays.asList("S", "M", "L", "XL", "2XL", "3XL", "4XL", "5XL", "6XL");

Then:

yourList.sort(sizeOrder);

If you want, you can build a Map<String, Integer> for the lookup:

Map<String, Integer> lookup =
    IntStream.range(0, desiredOrder.length())
        .boxed()
        .collect(Collectors.toMap(desiredOrder::get, i -> i));

And then do:

Comparator<String> sizeOrder = Comparator.comparing(lookup::get);

I'm not convinced that this will be any more performant than using List.indexOf, because the desiredOrder list is so small.

As with everything performance-related: use the one which you find most readable; profile if you think this is a performance bottleneck, and only then try alternatives.

like image 43
Andy Turner Avatar answered Oct 23 '22 10:10

Andy Turner