You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何生成一组可迭代对象的所有组合?Groovy代码相关咨询

生成镜片参数的所有组合:完善你的Groovy代码

嘿,我看你正在写一个生成镜片参数所有组合的Groovy方法,代码开头已经处理了sph、cyl、add的范围参数,但后面截断了。我来帮你补全这段代码,顺便解释下怎么高效生成所有可能的组合~

补全后的完整代码

首先,先给你补全并优化后的代码,适配镜片参数的常见场景:

private static List<Map> expandLensesPositions(Map entry) {
    def expandedPositions = []
    def entryCopy = entry.clone() as Map
    
    // 提取并移除范围参数,避免影响后续组合
    def sphFrom = entryCopy.remove("sphFrom") as BigDecimal
    def sphTo = entryCopy.remove("sphTo") as BigDecimal
    def cylFrom = entryCopy.remove("cylFrom") as BigDecimal
    def cylTo = entryCopy.remove("cylTo") as BigDecimal
    def addFrom = entryCopy.remove("addFrom") as BigDecimal
    def addTo = entryCopy.remove("addTo") as BigDecimal
    
    // 镜片参数常用步长是0.25,可根据需求调整
    def step = new BigDecimal("0.25")
    
    // 生成每个参数的所有可能值序列,保证精度统一
    def sphValues = []
    for (def sph = sphFrom; sph <= sphTo; sph += step) {
        sphValues.add(sph.setScale(2, BigDecimal.ROUND_HALF_UP))
    }
    
    def cylValues = []
    for (def cyl = cylFrom; cyl <= cylTo; cyl += step) {
        cylValues.add(cyl.setScale(2, BigDecimal.ROUND_HALF_UP))
    }
    
    def addValues = []
    for (def add = addFrom; add <= addTo; add += step) {
        addValues.add(add.setScale(2, BigDecimal.ROUND_HALF_UP))
    }
    
    // 生成所有参数的笛卡尔积组合
    sphValues.each { sph ->
        cylValues.each { cyl ->
            addValues.each { add ->
                def combination = new HashMap<>(entryCopy)
                combination.putAll([sph: sph, cyl: cyl, add: add])
                expandedPositions.add(combination)
            }
        }
    }
    
    return expandedPositions
}

关键细节解释

  • 克隆输入Map:我用entry.clone()是为了避免修改原始输入数据,保持数据的不可变性,防止后续代码意外污染原数据。
  • 步长与精度:镜片参数通常以0.25为增量,这里设置了固定步长,同时用setScale(2)保证所有参数都是两位小数,避免BigDecimal的精度问题。
  • 笛卡尔积生成:嵌套的each循环是Groovy里最直观的生成组合的方式,如果你以后要加更多参数(比如轴位axis),这种写法也容易扩展。

更简洁的笛卡尔积写法

如果觉得嵌套循环太繁琐,Groovy自带的combinations()方法可以帮你简化:

// 替换原有的嵌套each循环
def allCombinations = [sphValues, cylValues, addValues].combinations()
allCombinations.each { combo ->
    def combination = new HashMap<>(entryCopy)
    combination.putAll([sph: combo[0], cyl: combo[1], add: combo[2]])
    expandedPositions.add(combination)
}

这种写法更简洁,尤其是参数数量多的时候,可读性更好。

测试示例

来个实际调用的例子,看看效果:

def input = [
    sphFrom: new BigDecimal("-2.00"),
    sphTo: new BigDecimal("-1.50"),
    cylFrom: new BigDecimal("-0.50"),
    cylTo: new BigDecimal("0.00"),
    addFrom: new BigDecimal("1.00"),
    addTo: new BigDecimal("1.00"),
    lensType: "progressive"
]

def result = expandLensesPositions(input)
result.each { println it }

输出会是所有6种可能的组合:

[sph:-2.00, cyl:-0.50, add:1.00, lensType:progressive]
[sph:-2.00, cyl:0.00, add:1.00, lensType:progressive]
[sph:-1.75, cyl:-0.50, add:1.00, lensType:progressive]
[sph:-1.75, cyl:0.00, add:1.00, lensType:progressive]
[sph:-1.50, cyl:-0.50, add:1.00, lensType:progressive]
[sph:-1.50, cyl:0.00, add:1.00, lensType:progressive]

内容的提问来源于stack exchange,提问作者iRomul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:34:16