在制表符分隔文件中读取地图而不是Groovy中的列表

时间:2016-05-11 17:24:37

标签: groovy

我想在Groovy中的制表符分隔文件中阅读...

inputFile.eachLine { rawLine ->

   def line = rawLine.split('\t')
   def orderId = line[0]

但我不想记住哪个字段在哪个列号,我宁愿做类似......

的事情
 def orderId = line['ORDERID']

现在,如果我尝试这个,它会给出一个例外..

groovy.lang.MissingPropertyException: 
Exception evaluating property 'ORDERID' for java.util.Arrays$ArrayList

我认为是因为我在每个记录中都是以列表而不是地图的形式阅读。那么如何将这个文件作为地图阅读呢?

2 个答案:

答案 0 :(得分:1)

鉴于此制表符分隔文件:

-h

以下脚本使用Groovy 2.4.5和groovycsv(建议为tim_yates;我恰好正好使用它):

"City"  "Country"       "Year"
Paris   France  2016
Toronto Canada  2010

@Grab('com.xlson.groovycsv:groovycsv:1.1') import static com.xlson.groovycsv.CsvParser.parseCsv def file = args[0] def text = new File(file).getText() def data = parseCsv(text, separator: '\t') data.each { line -> println "city: " + line["City"] println "country: " + line["Country"] println "year: " + line["Year"] } 产生:

groovy MyScript.groovy my_file.csv

答案 1 :(得分:0)

有点死灵,但是如果有人对“手工”方法感兴趣,这会让您入门。我意识到上述库可能是更好的,所以这里出于教育目的。

如果发生以下情况,它将中断:

  1. 列大小!=任何特定的记录大小
  2. 文件中有空白行

FixtureMinion是我的测试环境中的本地类,使用类加载器显然不是加载文件的唯一方法。

在某些测试中,当我想要看起来像来自数据库的数据而不是实际上来自数据库的数据时,可以使用它。 YMMV。

static List<Map<String, String>> listOfMapFromTabSeparatedFile(String resourcFile) {
    // The list where the maps are "accumulated"
    List<Map<String, String>> accumulator = []
    URL fileLocation = FixtureMinion.class.getClassLoader().getResource(resourcFile)
    new File(fileLocation.toURI()).withReader { reader ->
        // get the columns
        List<String> columns = splitOnTabs(reader.readLine())
        reader.eachLine { line ->
            List<String> record = splitOnTabs(line)
            assert columns.size() == record.size()
            // magic happens
            accumulator << [columns, record].transpose().collectEntries { it }
        }
    }
    accumulator
}

static List<String> splitOnTabs(String stringToSplit) {
    stringToSplit.split("\t", -1) as List<String>
}

进一步,解释“魔术”激发了普通外壳

15:38 $ groovysh
Groovy Shell (2.4.9, JVM: 1.8.0_181)
Type ':help' or ':h' for help.
-----------------------------------------------------
groovy:000> col = ['a','b','c']
===> [a, b, c]
groovy:000> rec = ['x','y','z']
===> [x, y, z]
groovy:000> [col, rec].transpose()
===> [[a, x], [b, y], [c, z]]
groovy:000> [col, rec].transpose().collectEntries {it}
===> [a:x, b:y, c:z]

transpose在这里创建对,collectEntries将它们变成地图。