【问题标题】:Remove elements in a string separated by commas in groovy在groovy中删除用逗号分隔的字符串中的元素
【发布时间】:2018-10-17 19:36:37
【问题描述】:

我正在以这种方式构建一个字符串:

def presentationType = "${feedDisplayType}, ${moduleType}, ${cellType}"

发生的情况是,有时变量有空值,结果字符串显示这个空值,我必须避免显示空值。

我想知道是否有某种方法可以删除字符串中可能存在的空值,或者避免在它们出现时添加它。

我知道使用数组可以而且更容易,但我想以更直接的方式使用字符串。

提前感谢您的帮助。

【问题讨论】:

    标签: string groovy null remove-if


    【解决方案1】:

    有 3 个选项:

    1。 GString 插值

    def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
    

    2。使用StringBuilder

    def sb = new StringBuilder()
    if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
        sb.append(feedDisplayType)
        sb.append(', ')
    }
    if (moduleType != null && !moduleType.isEmpty()) {
        sb.append(moduleType)
        sb.append(', ')
    }
    if (cellType != null && !cellType.isEmpty()) {
        sb.append(cellType)
    }
    def presentationType = sb.toString()
    

    3。以, 为分隔符加入列表

    def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
    

    基准测试

    在得出结论之前,让我们使用GBench 工具对所有 3 种方法进行基准测试:

    @Grab(group='org.gperfutils', module='gbench', version='0.4.3-groovy-2.4')
    
    def feedDisplayType = 'test'
    def moduleType = null
    def cellType = ''
    
    def r = benchmark {
    
        'GString method' {
            def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
        }
        'StringBuilder method' {
            def sb = new StringBuilder()
            if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
                sb.append(feedDisplayType)
                sb.append(', ')
            }
            if (moduleType != null && !moduleType.isEmpty()) {
                sb.append(moduleType)
                sb.append(', ')
            }
            if (cellType != null && !cellType.isEmpty()) {
                sb.append(cellType)
            }
            def presentationType = sb.toString()
        }
        'Join list method' {
            def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
        }
    }
    r.prettyPrint()
    

    输出

    Environment
    ===========
    * Groovy: 2.4.12
    * JVM: OpenJDK 64-Bit Server VM (25.171-b10, Oracle Corporation)
        * JRE: 1.8.0_171
        * Total Memory: 236 MB
        * Maximum Memory: 3497 MB
    * OS: Linux (4.16.5-200.fc27.x86_64, amd64)
    
    Options
    =======
    * Warm Up: Auto (- 60 sec)
    * CPU Time Measurement: On
    
                          user  system  cpu  real
    
    GString method         265       2  267   268
    StringBuilder method    72       4   76    77
    Join list method       484       3  487   495
    

    结论

    如果您的目标是实现最高吞吐量,StringBuilder 方法是最好的方法(平均时间为 77 纳秒)。

    GString 方法比StringBuilder 慢几倍,并且由于单个 GString 中的所有条件语句,它的可读性要差得多。它也很容易出错 - 在这种情况下插入 String 时很容易出错。

    加入列表方法是最慢的一种(仅比 GString 方法慢大约 2 倍),但它是最干净的一种。而且它仍然非常快——在大多数情况下,495 纳秒是可以接受的。当然优化取决于具体的用例——如果你必须每秒执行这部分代码百万次,那么使用StringBuilder 会更有意义。

    基准极端案例

    为了使这个示例完整,让我们还看一下基准测试中的极端情况。我们使用相同的代码输入不同的内容。

    输入:

    def feedDisplayType = 'lorem ipsum'
    def moduleType = 'dolor sit amet'
    def cellType = '123456789'
    

    输出:

                          user  system  cpu  real
    
    GString method         387       1  388   390
    StringBuilder method   170       0  170   175
    Join list method       847       6  853   859
    

    输入:

    def feedDisplayType = ''
    def moduleType = ''
    def cellType = ''
    

    输出:

                          user  system  cpu  real
    
    GString method         237       5  242   242
    StringBuilder method    44       0   44    44
    Join list method       441       0  441   446
    

    【讨论】:

      【解决方案2】:

      编辑:此答案已更改,因为要求不为空词打印“,”。

      考虑:

      def feedDisplayType = 'abc'
      def moduleType = null
      def cellType = 'ijk'
      
      def f = { s, isLast = false ->
          def token = s ?: ''
          def seperator = (!s || isLast) ? '' : ',' 
          "${token}${seperator}"
      }
      
      def presentationType = "${f feedDisplayType}${f moduleType}${f cellType,true}"
      assert 'abc,ijk' == presentationType
      

      请注意,在函数调用中,括号在 Groovy 中是可选的,因此 ${f x} 等价于 ${f(x)}f 在早期版本中最初是 field,但为简洁起见,我将其缩短了。

      【讨论】:

      • 是的,这几乎就是我要找的东西,但我也必须避免,你的方法很有趣。
      • 这样会像:presentationType": ", , example" 并且应该是presentationType": "example"。谢谢
      • 如果要求避免使用逗号,那么您应该使用该信息更新问题。
      • 我已更改答案以解决“,”上的问题。关于空格的问题不清楚,所以我假设我们不想要额外的空格。
      猜你喜欢
      • 2021-11-12
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-12
      相关资源
      最近更新 更多