更绝妙的列表操作方式

发布于 2024-12-08 18:10:37 字数 535 浏览 0 评论 0原文

我有两个这样的列表:

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

我想要像这样操作 a 的 Groovier 方式:

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]

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

提前致谢。

I have two list like this :

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

I want the 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.

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

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

发布评论

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

评论(3

薄荷梦 2024-12-15 18:10:37

对于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

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.

划一舟意中人 2024-12-15 18:10:37

使用收集

响应 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
}

使用注入

您还可以使用注入,传入乘数和结果的映射,然后在最后取出结果:

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 来说很难甚至不可能)

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)

温馨耳语 2024-12-15 18:10:37
def a1 = [100:30, 200:60, 300:90]

a1.eachWithIndex{item,index ->
println item.key-((2**(index+1))*item.value)
i++
}
def a1 = [100:30, 200:60, 300:90]

a1.eachWithIndex{item,index ->
println item.key-((2**(index+1))*item.value)
i++
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文