我有两个这样的列表:
def a = [100,200,300]
def b = [30,60,90]
我希望Groovier以这样的方式操纵a
:
1)a
的第一个元素应更改为a[0]-2*b[0]
2)a
的第二个元素应更改为a[1]-4*b[1]
3)a
的第三个元素应更改为a[2]-8*b[2]
(前提是a
和b
的长度均为3
}
如果列表更改为map
,请说:
def a1 = [100:30, 200:60, 300:90]
在这种情况下如何进行相同的上述操作。
提前致谢。
答案 0 :(得分:4)
对于List
,我会选择:
def result = []
a.eachWithIndex{ item, index ->
result << item - ((2**index) * b[index])
}
对于Map
来说,它更容易一些,但仍需要外部状态:
int i = 1
def result = a.collect { k, v -> k - ((2**i++) * v) }
遗憾的是,在这种情况下,Groovy没有zip
的模拟,类似于zipWithIndex
或collectWithIndex
。
答案 1 :(得分:3)
在评论中回应Victor,你可以使用收集
来做到这一点def a = [100,200,300]
def b = [30,60,90]
// Introduce a list `c` of the multiplier
def c = (1..a.size()).collect { 2**it }
// Transpose these lists together, and calculate
[a,b,c].transpose().collect { x, y, z ->
x - y * z
}
你也可以使用inject
,传递乘数和结果的映射,然后在结尾处取出结果:
def result = [a,b].transpose().inject( [ mult:2, result:[] ] ) { acc, vals ->
acc.result << vals.with { av, bv -> av - ( acc.mult * bv ) }
acc.mult *= 2
acc
}.result
同样,你可以使用注入地图:
def result = a1.inject( [ mult:2, result:[] ] ) { acc, key, val ->
acc.result << key - ( acc.mult * val )
acc.mult *= 2
acc
}.result
使用inject
的优势在于您不需要声明外部变量,但缺点是难以读取代码(正如Victor在注释中指出的那样,这会对代码进行静态分析IDE和groovypp难以实现)
答案 2 :(得分:0)
def a1 = [100:30, 200:60, 300:90]
a1.eachWithIndex{item,index ->
println item.key-((2**(index+1))*item.value)
i++
}