首页 > 解决方案 > Groovy 匹配行和返回列

问题描述

首先,我是一个 Groovy 新手。我只对脚本做过小的调整。

我正在研究一个将用作 Jenkins 共享库的一部分的对象。这个想法是有一些通用的东西,可以根据传递给它的内容返回值。

@Grab('com.xlson.groovycsv:groovycsv:1.0')
import com.xlson.groovycsv.CsvParser

/**
 * Given matchingValue in matchingColumn return the value in returnColumn
 * Use verifyValue first to confirm the value is present
 * @param matchingValue The value that is in matchingColumn
 * @param matchingColumn The column to search
 * @param returnColumn The column to return
 * @return The value in returnColumn in the row of matchingValue
 * @see #matchValue(String)
 */
Object matchValue(String matchingValue, String matchingColumn, String returnColumn) {
    new File('test.csv').withReader { f ->
      def data = new CsvParser().parse(f)
      data.findAll{ (it.${matchingColumn} as String) == "${matchingValue}" }.each{return it.${returnColumn} }
    }
}

def match = matchValue('apple','type','origin')
println "${match}"

test.csv 的内容:

type,color,origin
apple,red,tree
banana,yellow,ground
avacado,green,ground
lemon,yellow,tree

当我运行这个脚本时,我得到:

Caught: groovy.lang.MissingMethodException: No signature of method: com.xlson.groovycsv.PropertyMapper.$() is applicable for argument types: (csvmap$_matchValue_closure1$_closure2$_closure4) values: [csvmap$_matchValue_closure1$_closure2$_closure4@3f3c966c]
Possible solutions: is(java.lang.Object), any(), any(groovy.lang.Closure), use([Ljava.lang.Object;), tap(groovy.lang.Closure), wait()
groovy.lang.MissingMethodException: No signature of method: com.xlson.groovycsv.PropertyMapper.$() is applicable for argument types: (csvmap$_matchValue_closure1$_closure2$_closure4) values: [csvmap$_matchValue_closure1$_closure2$_closure4@3f3c966c]
Possible solutions: is(java.lang.Object), any(), any(groovy.lang.Closure), use([Ljava.lang.Object;), tap(groovy.lang.Closure), wait()
    at csvmap$_matchValue_closure1$_closure2.doCall(csvmap.groovy:17)
    at csvmap$_matchValue_closure1.doCall(csvmap.groovy:17)
    at csvmap.matchValue(csvmap.groovy:15)
    at csvmap.run(csvmap.groovy:21)

我假设这是因为动态列名,但我不知道如何处理。

标签: groovy

解决方案


有两个主要问题:

  • 按名称访问属性不是通过it.${prop},而是通过 it."${prop}"-- 注意引号
  • each用于副作用; 假设您只想返回第一个匹配项,则需要find而不是findAll+ each

例如

@Grab('com.xlson.groovycsv:groovycsv:1.0')
import com.xlson.groovycsv.CsvParser

def matchValue(String matchingValue, String matchingColumn, String returnColumn) {
    new File('test.csv').withReader { f ->
        def data = new CsvParser().parse(f)
        data.find{ 
            (it."${matchingColumn}" as String) == "${matchingValue}" 
        }?."${returnColumn}"
    }
}

def match = matchValue('apple','type','origin')
println match
// → tree

推荐阅读