【问题标题】:Compare strings by natural order but ignoring string's prefix [duplicate]按自然顺序比较字符串,但忽略字符串的前缀 [重复]
【发布时间】:2021-02-11 11:46:04
【问题描述】:

我正在努力以自然顺序对字符串流(或列表,如果您愿意)进行排序,忽略前缀。 前缀始终以 let 开头,后面可以跟任何数字(例如 let12 或 let3021)

示例输入:

let3 art zero
let2 own kit dig
let1 art can

所需输出示例:

let1 art can
let3 art zero
let2 own kit dig

所以我尝试过的一个简单想法是执行以下操作:

list.stream().sorted();

但是数字妨碍了,产生以下输出:

let1 art can
let2 own kit dig
let3 art zero

如何以简单的方式实现此结果?理想的解决方案是比较器,或者我可以在流中使用的任何东西。

注意:我尝试使用 Comparator 失败了,因为前缀可以是任意长度。

感谢您的宝贵时间。

【问题讨论】:

    标签: java sorting java-stream comparator


    【解决方案1】:

    您正在回答自己的问题:使用比较器。

    Comparator<String> marcosPrefixIgnoringComparison =
        (a, b) -> a.substring(4).compareTo(b.substring(4));
    

    假设前缀被定义为“前 4 个字符”。如果它更多的是“字符串let,然后是任意位数”,则您必须执行其他操作。可能是正则表达式:

    Comparator<String> marcosPrefixIgnoringComparison =
        (a, b) -> a.replaceFirst("^let\\d+\\s+", "").compareTo(
          b.replaceFirst("^let\\d+\\s+", ""));
    

    您的问题在这里不是特别清楚“前缀”是什么意思。

    【讨论】:

    • 嗨,我的错,我已经用有关前缀的更多详细信息更新了问题。我对比较器的尝试失败了,因为前缀可以是任意长度。我对正则表达式知之甚少,我将深入探讨您的第二个答案并让您知道。感谢您的宝贵时间
    • @Marco 您还可以使用Comparator 中的静态方法在比较之前转换字符串。 comparing 方法的参数是转换字符串的Function。此函数适用于要进行比较的两个字符串。例如,Comparator.comparing(str -&gt; str.replaceFirst("^let\\d+\\s+", "")) 将产生与上述marcosPrefixIgnoringComparison 相同的结果。
    • ...如果您关心性能,您会将正则表达式编译为 Pattern 对象一次并保留它,以避免在每次比较时解析这个重要的正则表达式两次。
    • 谢谢Mc Emperor,更简洁明了。很高兴知道,Holger,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    相关资源
    最近更新 更多