我需要你的帮助按照查询。鉴于以下列表:
["2XL", "3XL", "4XL", "5XL", "6XL", "L", "M", "S", "XL"]
如何对其进行排序以使其按此顺序排列?
[“S”,“M”,“L”,“XL”,“2XL”,“3XL”,“4XL”,“5XL”,“6XL”]
请注意,并不总是存在每种尺寸。
答案 0 :(得分:16)
构建一个比较器,对您所需的订单进行查找:
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
列表太小了。
与所有与性能相关的内容:使用您认为最具可读性的内容;如果您认为这是性能瓶颈,只有然后尝试替代方案。
答案 1 :(得分:5)
一般方法将关注大小字符串背后的模式,而不仅仅是容纳样本输入。您有一个基本方向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
方法的类的名称。
答案 2 :(得分:2)
使用可能更有效且更明确的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);
}
答案 3 :(得分:0)
另一种方式可能是这样的:
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());
答案 4 :(得分:0)
这是完成大小排序的基本算法。该算法的基本思想是将大小的每个部分(import os
import shutil
print("----PROCESS STARTED----")
filelist = [] #list of files to be compressed
filegroup = set() #set for grouping files
basedir = "C:/Users/XYZ/" #base directory
extension = "jpg" #extension of the file to be compressed
extensionlen = 3 #extension length of the file to be compressed
folderstart = 0
folderend = 9
#list of files to be compressed
for f in os.listdir(basedir):
if f[-extensionlen:] == extension :
filelist.append(f)
#list of groups
for file in filelist:
filegroup.add(file[folderstart:folderend])
print(file)
#create folder for the group
for group in filegroup:
print(group)
if not os.path.isdir(basedir+group) :
os.mkdir(basedir+group)
#move files to the folders
for file in filelist:
os.rename(basedir+file,basedir+file[folderstart:folderend]+"/"+file)
#compress the folders
for group in filegroup:
shutil.make_archive(basedir+group, 'zip', basedir+group)
shutil.rmtree(basedir+group)
print("----PROCESS COMPLETED----")
,number
,modifier
)分解为相应的区域(unit
,[0, 1000)
,{{ 1}}),然后使用[1000, 1000_000)
来确定[1000_000, reset]
的方向。例如:
dir
上述解决方案仅适用于您的简单案例,因为您需要解析modifier
&amp; 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
答案 5 :(得分:0)
创建一个具有所有可能大小的Enum类,并向其中添加getEnum
方法以支持以数字开头的大小:
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());
}
}
在比较器中使用SizeEnum
类:
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));
答案 6 :(得分:0)
public static void SortSizes(String [] sizes, String [] sortedRadixArr) throws Exception{
//creating an int array with same length as sortedRadixArr
//Here each index of intRadix array is mapped to the index of sortedRadixArr
//Eg: intRadix = [0,0,0,0,0] ----> ["S","M","L","XL","2XL"]
int [] intRadix = new int[sortedRadixArr.length];
for(int i = 0; i < sizes.length; i++){
boolean matchFlag = false;
for(int j=0; j< sortedRadixArr.length; j++){
if(sizes[i] == sortedRadixArr[j]){
//Whenever the String is matched with the String of sortedRadixArr array,
//increment the value of intRadix array at the equivalent index of sortedRadixArr.
//This helps us to count number same strings(sizes). like two or more "S".
//We can't do that with sortedRadixArr as it is a String array.
intRadix[j]++;
matchFlag = true;
break;
}
}
if(!matchFlag){
throw new Exception("Invalid size found!");
}
}
int count = 0;
for(int k = 0; k < intRadix.length; k++){
//Loop thru intRadix array. It contains count of respective sizes(Strings) at each index.
//We will re-write sizes array in sorted order with help of intRadix as below.
while(intRadix[k] > 0){
sizes[count++] = sortedRadixArr[k];
intRadix[k]--;
}
}
}
}
此处,sortedRadixArr
是基数数组,即具有所有可能值的值:
["S", "M", "L", "XL", "2XL", "3XL", "4XL", "5XL", "6XL"]
sizes
是您要排序的数组:
["2XL", "3XL", "4XL", "5XL", "6XL", "L", "M", "S", "XL"]
它接受重复的值。