是否有 ruby​​ oneliner 可以在没有临时副本的情况下连接嵌套数组?

Posted

技术标签:

【中文标题】是否有 ruby​​ oneliner 可以在没有临时副本的情况下连接嵌套数组?【英文标题】:Is there a ruby oneliner to concat nested arrays without temporary copies? 【发布时间】:2016-11-20 13:19:38 【问题描述】:
a = [ 'a' ]
b = [ 'b' ]

def c

    return [ 'c' ], [ 'd' ]

end

a, b += c # -> would be awesome, but gives syntax error

a, b = a + c.first, b + c.last # clunky and will call method twice...

# desired result
#
a == [ 'a', 'c' ]
b == [ 'b', 'd' ]

现在我经常发现自己在写作:

t, tt = c
a += t
b += tt

但如果你问我,那有点难看。

编辑:单元素数组似乎让一些人感到困惑,因为下面的几个答案只是没有回答这个问题。通过让每个数组至少有 2 个元素,我更清楚地说明了这一点。

Edit2:我用 ruby​​ 核心提交了一个feature request,以在解构数组上实现复合赋值。

【问题讨论】:

请永远不要以您的方式修改答案。如果您认为没有人提供适合您的需求,请随时发布您自己的答案。 好的,不用担心,但它实际上会通过编辑回答这个问题......现在它并没有真正回答这个问题...... 这与您无关,除了您在给出所有提供的答案后重新提出了一个问题。您基本上有三个选择:接受答案,向上/向下投票并忽略它。即使您认为这会改善答案,也不允许您弄乱答案。 这不是“好的,不用担心”。 @mudasobwa 解释了为什么改变你的问题是不行的,尽管我不明白为什么需要告诉你,因为这些改变已经使答案变得毫无意义。让你的编辑站得到我的反对。 好的,我改回来。答案已经荒谬了。我所做的改变是为了让结构更加突出,而不是为了改变它。 【参考方案1】:
a,b = [a+b,c].transpose
  #=> [["a", "c"], ["b", "d"]] 
a #=> ["a", "c"] 
b #=> ["b", "d"] 

【讨论】:

transpose 加一。不知道。 这不起作用:它给出a = ["a", ["c"]] 的意思是它追加而不是连接。【参考方案2】:
a, b = (a+b).zip(c)
# a => ["a", "c"]
# b => ["b", "d"]

希望对你有帮助。

【讨论】:

(a+b).zip(c),不需要展平。 哦,真的.. 更好。你也可以添加你的答案。还是我应该更新我的答案? 非常好,比我建议的有所改进! 我知道我不需要展平。只要两个数组大小相同,ziptranspose 就可以互换。 这不起作用:它给出a = ["a", ["c"]] 的意思是它追加而不是连接。【参考方案3】:

由于有“没有临时副本”的要求,我将发布就地修改任意数量数组的解决方案

a1 = [ 'a1' ]
a2 = [ 'a2' ]
a3 = [ 'a3' ]
aa = [ a1, a2, a3 ]
cc = [ 'c1', 'c2', 'c3' ]

aa.each_with_object(cc.each)  |e, memo| e << memo.next 
#⇒ #<Enumerator: ["c1", "c2", "c3"]:each> # do not care, it’s memo

[a1, a2, a3]
#⇒ [ ["a1", "c1"], ["a2", "c2"], ["a3", "c3"] ]

cc 数组是否出于某种原因数组数组,正如它在问题中指定的那样,它应该在某个步骤上变平,具体取决于它应该如何添加到 @987654323 @数组。

【讨论】:

这行不通:它给出了a = ["a", ["c"]] 的意思是它追加而不是连接。但是,我设法对其进行了调整,使其真正起作用:[a,b].each_with_object(c.each) |e, memo| e.concat memo.next 。它仍然非常笨重和神秘,所以我怀疑我是否会将它用于简单的方法返回解构,但它确实可以扩展,公平竞争。 这对任何能够阅读到最后并将枚举器返回的内容展平的人都非常有效:aa.each_with_object(cc.each) |e, memo| e.&lt;&lt;(*memo.next) 【参考方案4】:

到目前为止,没有一个答案有效,所以现在我想出了nest_concat! (deep_concat 似乎用词不当,因为我们只想要一个深度):

class Array

    def nest_concat! other

        each_with_index  |arr, i| self[i].concat other[ i ] 

    end

    def nest_concat other

        d = map( &:dup )
        each_with_index  |arr, i| d[i].concat other[ i ] 

        d

    end

end

允许你写:

a = [ 'a', 'b' ]
b = [ 'c', 'd' ]

def c

    return [ 'A', 'B' ], [ 'C', 'D' ]

end

[ a, b ].nest_concat! c
p a
p b

给予

["a", "b", "A", "B"]
["c", "d", "C", "D"]

【讨论】:

截至欧洲中部时间 13:00,它给出的内容与问题中的“期望结果”部分相矛盾。 不,它没有。 This is the original question,从未改变,只是更新以帮助人们不要误解代码。这是此解决方案的原始问题:ideone.com/q8IAA2 return [ 'a' ], [ 'b' ] 在 Ruby 中返回 [ [ 'a' ], [ 'b' ] ],而不是 [ 'a', 'b' ]。你只是像其他人一样误解了它。这就是为什么问题的标题是关于连接嵌套数组的原因。 请停止对我所做的误解做出假设,并重新阅读问题中所需的输出。提示:"c""b" 不同。 对于def my_method; return [ 'c' ], [ 'd' ]; end,执行该方法返回["c", "d"]。当然,同样的事情,如果你给方法取另一个名字,比如c。如果您认为我们都错了,请自己尝试。顺便说一句,这里不需要关键字return

以上是关于是否有 ruby​​ oneliner 可以在没有临时副本的情况下连接嵌套数组?的主要内容,如果未能解决你的问题,请参考以下文章

ruby sidekiq_oneliners.rb

尝试/赶上 oneliner 可用吗?

如果 bash 命令的状态在某个范围内,则 Oneliner 用于失败

是否可以“卸载”(“不需要”)Ruby库?

是否有可能在没有活动互联网访问的情况下使用 zlib 等所有部门安装 Ruby?

Python oneliner初始化字典[重复]