Salesforce Apex class 对年份和年份范围进行排序,输出不正确

Salesforce Apex class to sort years and year ranges giving incorrect output

尝试编写一种排序方法,其中的输入类似于一串以逗号分隔的年份和年份范围 String input = '2017, 2018,2020-2023,1800-1700,2020,20a9,19z5-1990,2025,20261,2013';

期望得到一串以逗号分隔的年份和年份范围,并删除所有重复和无效的输入。

下面是 class 写的,它没有给我正确的输出

            public class sortYearAndYearRangesString {
              public static List<String> sortSpecialString(String input) {
                   system.debug(input);
                    List<String> inputList = input.split('');
                  system.debug(inputList);
                Map<Integer,String> stringMap = new Map<Integer,String>();
                  system.debug(stringMap);
                List<String> output = new List<String>();
                for (Integer i=0; i<inputList.size(); i++) {
                    String charac = inputList[i];
                    if(!charac.isAlphaNumeric()) {
                         system.debug(charac);
                        stringMap.put(i,charac);
                    }else {
                        output.add(charac);
                        system.debug(output);
                    }
                }
                String finalString =  String.join(output,'');
                  system.debug(finalString);
                List<String> resultList = finalString.reverse().split('');
                for( Integer I : stringMap.keySet() ){
                    system.debug(I);
                    resultList.add(I,stringMap.get(I));
                     system.debug(resultList);
                    
                   
                }
                  return resultList;      
                   }
                   
                   

尝试在 Anonymous Apex 中验证解决方案但没有成功

             public static void validateSolution() {
             String input = '2017, 2018,2020-2023,1800-1700,2020,20a9,19z5-1990,2025,20261,2013';
             List<Integer> expected = new List<Integer> {2013,2017,2018,2020,2021,2022,2023,2025};
             List<Integer> actual = sortYearAndYearRangesString(input);
             
             System.assertEquals(expected, actual, 'Invalid Results');
             }
            }

感谢您的帮助

此致

卡罗琳

我对class做了一些修改。

它确实增加了所有范围 - 并且不检查它们是否是有意义的年份。您需要在其中添加该逻辑(例如 1500-1600 会 return 1500-1600 之间的所有年份。最好将上限设置为 1900 或其他)

public class SortYearAndYearRangesString{
public static List<Integer> sortSpecialString(String input){
    List<String> inputList = input.split(',');
    Set<Integer> output = new Set<Integer>();
    system.debug('input ' + input);
    system.debug('inputList ' + inputList);
    for (String s : inputList){
        Set<Integer> tempSet = new Set<Integer>();
        s.remove(' ');
        if (s.contains('-')){
            //// break the ranges and fill in years
            List<String> tempSet2 = s.split('-');
            for (String s2 : tempSet2){
                try{
                    ///capture valid integers
                    Integer tempInt = Integer.valueOf(s2);
                    tempSet.add(tempInt);
                } catch (Exception e){
                    tempSet.clear();
                    break;
                }
            }
            System.debug('set ' + tempSet);
            if (tempSet.size() > 1){
                List<Integer> tempList = new List<Integer>(tempSet);
                tempList.sort ();
                Integer r = tempList.size() - 1;
                // iterate through the years
                for (Integer i = tempList.get(0); i < tempList.get(r); i++){
                    tempSet.add(i) ;
                }
            }
        } else{
            try{
                ///capture valid integers
                Integer tempInt = Integer.valueOf(s);
                tempSet.add(tempInt);
            } catch (Exception e){
                continue;
            }
        }
        output.addAll(tempSet);
    }

    // output is currently set of ints, need to convert to list of integer

    List<Integer> finalOutput = new List<Integer>(output);
    finalOutput.sort ();
    System.debug('finalOutput :' + finalOutput);
    return finalOutput;
}}

根据您的测试用例,您还应该至少定义一个最大值常量,以便排除20261。可能你也需要一个最低限度。
我使用 1700 作为最小值和 4000 作为最大值,因为这些是日期或数据时间字段的限制:docs
此外,该方法必须 return a List<Integer> 而不是 List<String>.
您不需要 Map,只需 Set 即可。

public class SortYearAndYearRangesString {
    private static final Integer MAX_YEAR = 4000;
    private static final Integer MIN_YEAR = 1700;

    public static List<Integer> sortSpecialString(String input) {
        Set<Integer> output = new Set<Integer>();
        List<String> yearsList = input.split(',');
        for (String yearString : yearsList) {
            yearString = yearString.trim();
            if (yearString.isNumeric()) {
                try {
                    Integer year = Integer.valueOf(yearString);
                    if (year >= MIN_YEAR && year <= MAX_YEAR) {
                        output.add(year);
                    }
                } catch (TypeException e) {
                    System.debug(e.getMessage());
                }
            } else {
                List<String> range = yearString.split('-');
                if (range.size() == 2 && range[0].isNumeric() && range[1].isNumeric()) {
                    try {
                        // Modify the following two lines once you know how to handle range like 1300-1500 or 3950-4150
                        Integer firstYear = Math.max(Integer.valueOf(range[0]), MIN_YEAR);
                        Integer lastYear = Math.min(Integer.valueOf(range[1]), MAX_YEAR);
                        while (firstYear <= lastYear) {
                            output.add(firstYear++);
                        }
                    } catch (TypeException e) {
                        System.debug(e.getMessage());
                    }
                }
            }
        }
        List<Integer> sortedYears = new List<Integer>(output);
        sortedYears.sort();
        return sortedYears;
    }
}

如果超出边界的范围(如 1300-15003950-4150)应被视为无效并跳过,请更改这些行

Integer firstYear = Math.max(Integer.valueOf(range[0]), MIN_YEAR);
Integer lastYear = Math.min(Integer.valueOf(range[1]), MAX_YEAR);
while (firstYear <= lastYear) {
    output.add(firstYear++);
}

如下:

Integer firstYear = Integer.valueOf(range[0]);
Integer lastYear = Integer.valueOf(range[1]);
if (firstYear >= MIN_YEAR && lastYear <= MAX_YEAR) {
    while (firstYear <= lastYear) {
        output.add(firstYear++);
    }
}

我使用以下代码在匿名控制台中对其进行了测试:

String input = '2017, 2018,2020-2023,1800-1700,2020,20a9,19z5-1990,2025,20261,2013';
List<Integer> expected = new List<Integer> {2013,2017,2018,2020,2021,2022,2023,2025};
List<Integer> actual = SortYearAndYearRangesString.sortSpecialString(input);
System.debug(actual);
System.assertEquals(expected, actual, 'Invalid Results');

input = '1500,2017, 2018,2020-2023,1800-1700,2020,20a9,19z5-1990,2025,20261,2013,3998-4002';
expected = new List<Integer> {2013,2017,2018,2020,2021,2022,2023,2025,3998,3999,4000};
actual = SortYearAndYearRangesString.sortSpecialString(input);
System.assertEquals(expected, actual, 'Invalid Results');