1

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

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

有没有更短/更好的方法来做到这一点?

4

3 回答 3

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 }
于 2013-04-24T12:51:54.740 回答
1

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

referenceFile.collect { it.tokenize( '\t' ) }.collectEntries { k, v -> [ k.toLowerCase(), v ] }
于 2013-04-25T06:42:13.573 回答
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

因为它处理带引号的字符串

于 2013-04-24T12:18:03.580 回答