Groovier方法将tsv文件解析成map

时间:2013-04-24 12:00:54

标签: groovy

我有一个“key \ t value”形式的tsv文件,我需要读入一张地图。目前我是这样做的:

referenceFile.eachLine { line ->
    def (name, reference) = line.split(/\t/)
    referencesMap[name.toLowerCase()] = reference
}

有更短/更好的方法吗?

3 个答案:

答案 0 :(得分:4)

已经很短了。我能想到两个答案:

首先避免创建临时地图对象:

referenceFile.inject([:]) { map, line ->
    def (name, reference) = line.split(/\t/)
    map[name.toLowerCase()] = reference
    map
}

第二个更具功能性:

referenceFile.collect { it.split(/\t/) }.inject([:]) { map, val -> map[val[0].toLowerCase()] = val[1]; map }

答案 1 :(得分:1)

我能想到的另一种方法就是使用像你在Commons IO中找到的迭代器:

@Grab( 'commons-io:commons-io:2.4' )
import org.apache.commons.io.FileUtils

referencesMap = FileUtils.lineIterator( referenceFile, 'UTF-8' )
                         .collectEntries { line ->
  line.tokenize( '\t' ).with { k, v ->
    [ (k.toLowerCase()): v ]
  }
}

或使用CSV解析器:

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

referencesMap = referenceFile.withReader { r ->
  parseCsv( [ separator:'\t', readFirstLine:true ], r ).collectEntries {
    [ (it[ 0 ].toLowerCase()): it[ 1 ] ]
  }
}

但它们都不短,也不一定更好......

虽然我更喜欢选项2,因为它可以处理如下情况:

"key\twith\ttabs"\tvalue

因为它处理引用的字符串

答案 2 :(得分:1)

这是评论tim_yates添加到melix的答案中,我认为这是最短/最清楚的答案:

referenceFile.collect { it.tokenize( '\t' ) }.collectEntries { k, v -> [ k.toLowerCase(), v ] }