gpt4 book ai didi

ruby - 将 Ruby 元素数组转换为带索引的计数哈希

转载 作者:数据小太阳 更新时间:2023-10-29 07:45:59 24 4
gpt4 key购买 nike

在 Ruby 中给定一个二维数组:

[ [1, 1, 1],
[1, 1],
[1, 1, 1, 1],
[1, 1]
]

我想创建一个哈希,其中键是每个内部数组的计数,值是原始数组的索引数组,其内部数组大小具有特定计数。生成的哈希将是:

{ 2 => [1, 3], 3 => [0], 4 => [2] }

我如何在 Ruby 中简洁地表达这个功能?我正在尝试类似于 Hash.new([]).tap { |h| array.each_with_index { |a, i| h[a.length] << i } } 的东西, 但生成的哈希为空。

最佳答案

您的代码有两个问题。第一个是当h是空的,你写,比方说,h[2] << 1 , 自 h没有 key 2 , h[2]返回默认值,因此该表达式变为 [] << 1 #=> [1] ,但是[1]没有附加到散列,所以没有添加键和值。

你需要写h[2] = h[2] << 1 1。如果这样做,您的代码将返回 h #=> {3=>[0, 1, 2, 3], 2=>[0, 1, 2, 3], 4=>[0, 1, 2, 3]} .不幸的是,这仍然不正确,这将我们带到您的代码的第二个问题:您没有正确定义新创建的散列的默认值。

首先要注意的是

h[3].object_id
#=> 70113420279440
h[2].object_id
#=> 70113420279440
h[4].object_id
#=> 70113420279440

啊哈,这三个值都是同一个对象! new的论点 []h[k] 返回什么时候h没有 key k .问题是所有键都返回相同的数组 k添加到散列中,因此您要将键值对添加到第一个新键的空数组中,然后将第二个键值对添加到相同数组中以获取下一个新键,等等。请参阅下文了解如何定义散列。

通过这两项更改,您的代码可以正常工作,但我建议按如下方式编写。

arr = [ [1, 1, 1], [1, 1], [1, 1, 1, 1], [1, 1] ]

arr.each_with_index.with_object(Hash.new {|h,k| h[k]=[]}) { |(a,i),h|
h[a.size] << i }
#=> {3=>[0], 2=>[1, 3], 4=>[2]}

使用 Hash::new 的形式它使用一个 block 来计算哈希的默认值(即当哈希 h[k] 没有键 hk 返回的值),

arr.each_with_index.with_object({}) { |(a,i),h| (h[a.size] ||= []) << i }
#=> {3=>[0], 2=>[1, 3], 4=>[2]}

两者实际上是:

h = {}
arr.each_with_index do |a,i|
sz = a.size
h[sz] = [] unless h.key?(sz)
h[a.size] << i
end
h #=> {3=>[0], 2=>[1, 3], 4=>[2]}

另一种方法是使用 Enumerable#group_by ,在获取每个内部数组的索引后,按数组大小分组。

h = arr.each_with_index.group_by { |a,i| a.size }
#=> {3=>[[[1, 1, 1], 0]],
# 2=>[[[1, 1], 1], [[1, 1], 3]],
# 4=>[[[1, 1, 1, 1], 2]]}
h.each_key { |k| h[k] = h[k].map(&:last) }
#=> {3=>[0], 2=>[1, 3], 4=>[2]}

1 表达式 h[2] = h[2] << 1使用方法 Hash#[]=Hash#[] ,这就是为什么 h[2]= 的左侧不返回默认值。这个表达式也可以写成 h[2] ||= [] << 1 .

关于ruby - 将 Ruby 元素数组转换为带索引的计数哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41083683/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com