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

I need your help following the request. Given the following list:

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

How to sort it so that it is in that order?

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

Please note that each size is not always present.

+7
source share
6 answers

, . , S, M L ( M), .

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;
}

,

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());

Q48298432 , numerical.

+6

, :

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

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

:

yourList.sort(sizeOrder);

, Map<String, Integer> :

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

:

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

, , List.indexOf, desiredOrder .

: , ; , , .

+16

, , , , enum.

// Sizes in sort order.
enum Size {
    SMALL("S"),
    MEDIUM("M"),
    LARGE("L"),
    EXTRA_LARGE("XL"),
    EXTRA2_LARGE("2XL"),
    EXTRA3_LARGE("3XL"),
    EXTRA4_LARGE("4XL"),
    EXTRA5_LARGE("5XL"),
    EXTRA6_LARGE("6XL");
    private final String indicator;

    Size(String indicator) {
        this.indicator = indicator;
    }

    static final Map<String,Size> lookup = Arrays.asList(values()).stream()
            .collect(Collectors.toMap(
                    // Key is the indicator.
                    s -> s.indicator,
                    // Value is the size.
                    s-> s));

    public static Size lookup(String s) {
        return lookup.get(s.toUpperCase());
    }

    // Could be improved to handle failed lookups. 
    public static final Comparator<String> sizeOrder = (o1, o2) -> lookup(o1).ordinal() - lookup(o2).ordinal();
}

public void test(String[] args) {
    List<String> test = Arrays.asList("S","6XL", "L");
    Collections.sort(test, Size.sizeOrder);
    System.out.println(test);
}
+2

:

List<String> desiredOrder = Arrays.asList("S", "M", "L", "XL", "2XL", "3XL", "4XL", "5XL", "6XL");
 String [] array = new String[desiredOrder.size()];
   list.forEach(s->{
       if (desiredOrder.indexOf(s) != -1)
             array[desiredOrder.indexOf(s)] = s;
   });

List<String> set= Stream.of(array).filter(Objects::nonNull).collect(Collectors.toList());

Set<Integer> integers = new HashSet<>();
    list.forEach(s -> {
        if (desiredOrder.indexOf(s) != -1) {
            integers.add(desiredOrder.indexOf(s));
        }
    });

    List<String> sortedItems = integers.stream()
                                       .sorted()
                                       .map(i->desiredOrder.get(i))
                                       .collect(Collectors.toList());
0

. (number, modifier, unit) ([0, 1000), [1000, 1000_000), [1000_000, reset]), dir modifier. :

class Size {
  public static int sizeToInt(String size) {
    int n = size.length(), unit = size.charAt(n - 1), dir = unit == 'S' ? 1 : -1;
    //use a separate method to parse the number & extra modifier if needed
    int i = 0;
    int number = n > 1&&Character.isDigit(size.charAt(i)) ? size.charAt(i++) : '1';
    int modifier = i + 1 < n ? size.charAt(i) : 0;
        return -1 * (unit * 1000_000 + dir * (modifier * 1000 + number));
  }
}

, , , number modifier , region s. Comparator :

Comparator<String> sizeComparator = Comparator.comparingInt(Size::sizeToInt);

List<String> sizes = Arrays.asList(
    "3XL", "2XL", "XL",
    "5L", "2L", "L",
    "5M", "2M", "M",
    "S", "2S", "3S",
    "XS", "2XS", "3XS"
);


sizes.sort(sizeComparator);

System.out.println(sizes);
//                  ^--- [
//                         "3XS", "2XS", "XS",
//                         "3S", "2S", "S",
//                         "M", "2M", "5M",
//                         "L", "2L", "5L",
//                         "XL", "2XL", "3XL"
//                       ]
0
source

Create an Enum class with all possible sizes and add a method to it getEnumto support sizes starting with a number:

public enum SizeEnum
{
    S("S"), M("M"), L("L"), XL("XL"), TWO_XL("2XL"), THREE_XL("3XL"), FOUR_XL("4XL"), FIVE_XL("5XL"), SIX_XL("6XL");

    private String value;

    SizeEnum(String value){
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public static SizeEnum getEnum(String value) {
        return Arrays.stream(values())
                .filter(v -> v.getValue().equalsIgnoreCase(value))
                .findAny()
                .orElseThrow(() -> new IllegalArgumentException());
    }
}

Use the class SizeEnumin the comparator:

List<String> sizes = Arrays.asList("2XL", "3XL", "4XL", "5XL", "6XL", "L", "M", "S", "XL");
sizes.sort(Comparator.comparing(v -> SizeEnum.getEnum(v.toUpperCase())));
sizes.stream().forEach(l -> System.out.println(l));
0
source

All Articles