我有一个“key \t value”形式的tsv文件,我需要读入地图。目前我这样做:
referenceFile.eachLine { line ->
def (name, reference) = line.split(/\t/)
referencesMap[name.toLowerCase()] = reference
}
有没有更短/更好的方法来做到这一点?
我有一个“key \t value”形式的tsv文件,我需要读入地图。目前我这样做:
referenceFile.eachLine { line ->
def (name, reference) = line.split(/\t/)
referencesMap[name.toLowerCase()] = reference
}
有没有更短/更好的方法来做到这一点?
已经很短了。我能想到的两个答案:
第一个避免创建临时地图对象:
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 }
这是 tim_yates 添加到 melix 答案中的评论,我认为这是最短/最清晰的答案:
referenceFile.collect { it.tokenize( '\t' ) }.collectEntries { k, v -> [ k.toLowerCase(), v ] }
我能想到的唯一其他方法是使用您在 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
因为它处理带引号的字符串