所以我有一个看起来像这样的字符串:
def recalculate
from, to = params[:from], params[:to]
if from.empty? || to.empty?
redirect_to tarriff_path(@tarriff), alert: "Can't be empty"
elsif ???
redirect_to tarriff_path(@tarriff), alert: "Should be date"
else
...
redirect_to tarriff_path(@tarriff), notice: "Was recalculated"
end
end
我的最终目标是将此String拆分为Multimap,如下所示:
text = "foo/bar;baz/qux"
我还为LinkedHashMap的metaClass添加了Multimap-support:
["level1" : ["foo", "baz"], "level2" : ["bar", "qux"]]
String需要以分号分割,然后再以forforlash分割。目前我在嵌套的for循环中填充我的Multimap,但显然有一种Groovier方法。因此,我想知道我的选择是什么?
我正在思考以下几点:
LinkedHashMap.metaClass.multiPut << { key, value ->
delegate[key] = delegate[key] ?: []; delegate[key] += value
}
答案 0 :(得分:3)
您可以在返回的地图上使用withDefault
来摆脱三元:
def text = "foo/bar;baz/qux;foo/bar/woo"
def result = text.split(';')*.split('/').inject([:].withDefault {[]}) { map, value ->
value.eachWithIndex { element, idx ->
map["level${idx+1}"] << element
}
map
}
assert result == [level1:['foo', 'baz', 'foo'], level2:['bar', 'qux', 'bar'], level3:['woo']]
如果您不想在结果中使用重复项,那么您可以在withDefault中使用Set(然后转换回List):
def text = "foo/bar;baz/qux;foo/bar/woo"
def result = text.split(';')*.split('/').inject([:].withDefault {[] as Set}) { map, value ->
value.eachWithIndex { element, idx ->
map["level${idx+1}"] << element
}
map
}.collectEntries { key, value -> [key, value as List] }
assert result == [level1:['foo', 'baz'], level2:['bar', 'qux'], level3:['woo']]
答案 1 :(得分:1)
我接受它,我不会认为它非常聪明但我觉得它更容易阅读:
def myMap = [:]
text.split(';').eachWithIndex{ entry, index ->
myMap << ["level${index + 1}": entry.split('/')]
}
如果您使用的是Groovy 2.4.0或更高版本,则可以使用已添加到withIndex()
的{{1}}方法:
java.lang.Iterable