开发者

Groovier way of manipulating the list

I have two list like this :

def a = [100,200,300]
def b = [30,60,90]

I want th开发者_Python百科e Groovier way of manipulating the a like this :

1) First element of a should be changed to a[0]-2*b[0]

2)Second element of a should be changed to a[1]-4*b[1]

3)Third element of a should be changed to a[2]-8*b[2]

(provided that both a and b will be of same length of 3)

If the list changed to map like this, lets say:

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

how one could do the same above operation in this case.

Thanks in advance.


For List, I'd go with:

def result = []
a.eachWithIndex{ item, index ->
  result << item - ((2**index) * b[index])
}

For Map it's a bit easier, but still requires an external state:

int i = 1
def result = a.collect { k, v -> k - ((2**i++) * v) }

A pity, Groovy doesn't have an analog for zip, in this case - something like zipWithIndex or collectWithIndex.


Using collect

In response to Victor in the comments, you can do this using a collect

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
}

Using inject

You can also use inject, passing in a map of multiplier and result, then fetching the result out at the end:

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

And similarly, you can use inject for the map:

def result = a1.inject( [ mult:2, result:[] ] ) { acc, key, val ->
  acc.result << key - ( acc.mult * val )
  acc.mult *= 2
  acc
}.result

Using inject has the advantage that you don't need external variables declared, but has the disadvantage of being harder to read the code (and as Victor points out in the comments, this makes static analysis of the code hard to impossible for IDEs and groovypp)


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

a1.eachWithIndex{item,index ->
println item.key-((2**(index+1))*item.value)
i++
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜