【问题标题】:Sort a List of Image Names in Groovy在 Groovy 中对图像名称列表进行排序
【发布时间】:2013-11-15 13:14:23
【问题描述】:

我正在尝试对图像名称列表进行排序。为简单起见,我将其放置在表单的示例 Groovy 列表中:

imageNames=[
'20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C01.tif',
'20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C03.tif',
'20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A02Z01C04.tif',
'20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A03Z01C02.tif'
]

我希望能够按照图像名称后缀中的任何 T、F、L、A、Z 或 C 代码的数字顺序对该列表进行排序。

例如,如果要根据 C 代码对列表进行排序,则它应该按以下顺序出现:

  1. '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C01.tif',
  2. '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A03Z01C02.tif',
  3. '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C03.tif',
  4. '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A02Z01C04.tif'

我曾想过使用比较器来使用默认的 Groovy 集合排序方法。但是,我不确定如何将比较器直接写入闭包。 我想要类似的东西

imageNames.sort{comparator_for_C}

我可以为每个 T、F、L、A、Z 和 C 代码编写特定的比较器。

【问题讨论】:

    标签: list sorting collections groovy comparator


    【解决方案1】:

    如果图像文件的名称保持不变,直到第二个_,您可以跳过下面的逻辑中的拆分。我想保持安全。

    def imageNames=[
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C01.tif',
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C03.tif',
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A02Z01C04.tif',
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A03Z01C02.tif'
    ]
    
    def comparator = {str->
        [
          compare: {a,b->
              a.split(/_/)[2].dropWhile{it != str} <=> 
              b.split(/_/)[2].dropWhile{it != str}
          }
        ] as Comparator
    }
    
    def comp = ['T', 'F', 'A', 'Z', 'C'].collectEntries{[it, comparator(it)]}
    
    assert imageNames.sort(comp.'C') == [
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C01.tif',
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A03Z01C02.tif',
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C03.tif',
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A02Z01C04.tif'
    ]
    

    同样适用于其他字符:

    imageNames.sort(comp.'A')
    imageNames.sort(comp.'T') ....
    

    【讨论】:

    • 不错!如果比较器像他喜欢的那样工作,这是一个很好的解决方案。
    • 除了提供一个可用且优雅的解决方案之外,这个答案向我介绍了我不知道的 dropWhile 方法。谢谢!
    【解决方案2】:

    只需单独制作比较器,这样就可以了-

       def comparator_for_c = { }
       def sortedList = imageNames.sort(comparator_for_c)
    

    或者是这样的:

    def comparators = [c:{}, t:{}, ...]
    def sortedListForC = imageNames.sort(comparators.c)
    

    AS 示例代码:

    def imageNames = ['20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C01.tif',
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A01Z01C03.tif',
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A02Z01C04.tif',
    '20131018PKH26DRAQ5HOECHST1_A01_T0001F001L01A03Z01C02.tif']
    
    def sorters = [sort_c:{a, b -> b <=> a }, sort_t:{}]
    
    println "DefaultSort ${imageNames.sort()}"
    
    println "c sort: ${imageNames.sort(sorters.sort_c)}"
    

    只需将您的自定义比较器放在排序器映射中,然后调用您想要的比较器。

    【讨论】:

      【解决方案3】:

      考虑以下几点:

      imageNames.sort { def a, def b ->
          def rank = 0
      
          def matcherA = (a =~ /.*(...)\.tif/)
          def codeA = matcherA[0][1]
          def matcherB = (b =~ /.*(...)\.tif/)
          def codeB = matcherB[0][1]
      
          // add your own comparison logic here as desired:        
          rank = codeA.compareTo(codeB)
      
          rank
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-06
        相关资源
        最近更新 更多