Groovier操纵列表的方式

时间:2011-10-07 05:46:17

标签: groovy

-->

我有两个这样的列表:

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]

(前提是ab的长度均为3}

如果列表更改为map,请说:

def a1 = [100:30, 200:60, 300:90]

在这种情况下如何进行相同的上述操作。

提前致谢。

3 个答案:

答案 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的模拟,类似于zipWithIndexcollectWithIndex

答案 1 :(得分:3)

使用collect

在评论中回应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++
}
相关问题
最新问题