属性的点字符串

发布于 2024-12-02 09:22:21 字数 280 浏览 1 评论 0原文

我有一个类似于这样的字符串哈希:

Map map = ['a.b.c': 'Hi']

...我需要在 gradle 中使用它来扩展这样的表达式:

This is a greeting: ${a.b.c}

如果我将 gradle 复制任务与 Expand 一起使用,我将收到一条错误消息“没有这样的属性:a '。

有什么方法可以让 gradle/groovy 将该映射转换为我需要解析的属性吗?

I've got a hash of strings similar to this:

Map map = ['a.b.c': 'Hi']

... that I need to use in gradle to expand an expression like this:

This is a greeting: ${a.b.c}

If I use the gradle copy task with expand I will get an error message 'No such property: a'.

Is there any way to get gradle/groovy to convert that map into the properties I need to resolve?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

神仙妹妹 2024-12-09 09:22:21

我找不到内置的答案,但它是一个完整的、独立的方法,可以用作 Map 上的元方法来执行您想要的操作:

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"]]]

它还允许使用与 .< 不同的分隔符/code>,只需将分隔符传递到 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

I couldn't find a built-in answer, but it here is a complete, self-contained method that can be used as a meta method on Map to do what you want:

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"]]]

It also allows for different separators than ., just pass the separator into the expandKeys method

If you want to use it like a normal function, then you can do this instead:

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"]]]

The main trick, besides merging the maps, is to split then reverse each key. Then the final hierarchy can be built up backwards. Also, there may be a better way to handle the merge, because I don't like the hanging a at the end.

马蹄踏│碎落叶 2024-12-09 09:22:21

我对 Gradle 一无所知,但也许这会有所帮助......

如果你有一个 Map

Map map = ['a.b.c': 'Hi']

那么你无法使用 'Hi' 检索值

map.a.b.c

相反,你必须使用:

map.'a.b.c'

map['a.b.c']

I don't know anything about Gradle but maybe this will help....

If you have a Map

Map map = ['a.b.c': 'Hi']

Then you can't retrieve the value 'Hi' using

map.a.b.c

Instead, you must use:

map.'a.b.c'

or

map['a.b.c']
痴意少年 2024-12-09 09:22:21

我不太确定您的需求是什么,但如果您只需要替换类似属性的标记,而不需要 Groovy 模板的全部功能,则可以将 filter() 方法与 Ant 结合使用ReplaceTokens 类比 expand() 更安全(也更快)。请参阅 Gradle 用户指南中的过滤文件

I'm not exactly sure what your needs are, but if you just need to replace property-like tokens and don't need the full power of Groovy templates, the filter() method in combination with Ant's ReplaceTokens class is a safer (and faster) bet than expand(). See Filtering files in the Gradle User Guide.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文