带点字符串性能
我有字符串类似这样的哈希:带点字符串性能
Map map = ['a.b.c': 'Hi']
...我需要的gradle中使用扩展这样的表达式:
This is a greeting: ${a.b.c}
如果我在扩展时使用gradle copy任务,我会收到一条错误消息'没有这样的属性:a'。
有没有什么办法让gradle产出/常规该地图转换成我需要解决的属性?
我不确定你的需求是什么,但是如果你只需要替换财产状的标记,并且不需要Groovy模板的全部功能,filter()
方法与Ant的ReplaceTokens
类相结合就更安全了(和更快)下注比expand()
。请参阅Gradle用户指南中的Filtering files。
我不知道什么摇篮,但也许这将帮助....
如果你有一个地图
Map map = ['a.b.c': 'Hi']
那么你就不能检索使用
值“嗨”map.a.b.c
相反,你必须使用:
map.'a.b.c'
或
map['a.b.c']
是;这是我原来的问题。但是,我认为这是一个常见问题,有解决方案;可能是建筑者的形式。 – thoredge
我无法找到一个内置的答案,但在这里是一个可以被用来作为地图元方法去做你想做的一个完整的,自包含的方法:
Map map = ['a.b.c': 'Hi', 'a.b.d': 'Yo', 'f.g.h': 'Howdy']
Map.metaClass.expandKeys = { separator = '.' ->
def mergeMaps = { a, b ->
b.each{ k, v ->
if(a[k] && (v instanceof Map)) {
mergeMaps(a[k], v)
} else {
a[k] = v
}
}
a
}
delegate.inject([:]){ result, k, v ->
mergeMaps(result, k.tokenize(separator).reverse().inject(v){last, subkey -> [(subkey):last] })
}
}
assert map.expandKeys() == [a:[b:[c:"Hi", d:"Yo"]], f:[g:[h:"Howdy"]]]
它还允许不同的分离比.
,只是通过分隔成expandKeys
方法
如果你想使用它像一个正常的功能,那么你就可以做到这一点,而不是:
Map map = ['a.b.c': 'Hi', 'a.b.d': 'Yo', 'f.g.h': 'Howdy']
def expandKeys = { Map input, separator = '.' ->
def mergeMaps = { a, b ->
b.each{ k, v ->
if(a[k] && (v instanceof Map)) {
mergeMaps(a[k], v)
} else {
a[k] = v
}
}
a
}
input.inject([:]){ result, k, v ->
mergeMaps(result, k.tokenize(separator).reverse().inject(v){last, subkey -> [(subkey):last] })
}
}
assert expandKeys(map) == [a:[b:[c:"Hi", d:"Yo"]], f:[g:[h:"Howdy"]]]
主要的窍门,除了合并地图,是分裂然后反转每个键。然后最后的层次结构可以向后建立。此外,可能有更好的方式来处理合并,因为我不喜欢末尾挂着a
。
我忘了提及,如果您的原始地图包含子地图作为值,则此示例可能无法按您期望的方式工作。 (它们将被合并,而不是保持原样。)解决方案是一个更复杂的函数,它在对字符串进行标记时进行合并。即使那样,你*可能会在子地图上遇到一些问题。 – OverZealous
我在运行Gradle或Groovysh内遇到了一些麻烦。我得到了错误'groovy.lang.MissingPropertyException'。由于并发症(即你不能同时拥有a和a.b),我决定不这样做。 – thoredge
好的和工作的解决方案+1 – zellus
过滤器不接受multichar令牌。然而,最终扩大工作的麻烦,超过了更换所有令牌的麻烦。 – thoredge