从两个不同大小的数组中创建一个散列,并进行迭代,直到没有一个键是空的

时间:2022-09-16 12:53:58

Having two arrays of different sizes, I'd like to get the longer array as keys and the shorter one as values. However, I don't want any keys to remain empty, so that is why I need to keep iterating on the shorter array until all keys have a value.

有两个不同大小的数组,我想要将较长的数组作为键,而将较短的数组作为值。但是,我不希望任何键保持为空,所以我需要在较短的数组上不断迭代,直到所有键都具有值。

EDIT: I want to keep array longer intact, but without empty values, that means keep iterating on shorter until all keys have a value.

编辑:我想让数组保持更长的完整状态,但是没有空值,这意味着在所有键都有一个值之前,要在更短的时间内进行迭代。

longer  = [1, 2, 3, 4, 5, 6, 7]
shorter = ['a', 'b', 'c']

Hash[longer.zip(shorter)]
#=> {1=>"a", 2=>"b", 3=>"c", 4=>nil, 5=>nil, 6=>nil, 7=>nil}

Expected Result

预期的结果

#=> {1=>"a", 2=>"b", 3=>"c", 4=>"a", 5=>"b", 6=>"c", 7=>"a"}

3 个解决方案

#1


7  

Here's an elegant one. You can "loop" the short array

这是一个优雅的人。您可以“循环”短数组

longer  = [1, 2, 3, 4, 5, 6, 7]
shorter = ['a', 'b', 'c']

longer.zip(shorter.cycle).to_h # => {1=>"a", 2=>"b", 3=>"c", 4=>"a", 5=>"b", 6=>"c", 7=>"a"}

#2


1  

A crude way until you find something more elegant: Slice the longer array as per length of shorter one, and iterate over it to re-map the values.

一种粗略的方法,直到您找到更优雅的方法:按较短数组的长度对较长的数组进行切片,并对其进行迭代以重新映射值。

mapped = longer.each_slice(shorter.length).to_a.map do |slice|
           Hash[slice.zip(shorter)]
         end
=> [{1=>"a", 2=>"b", 3=>"c"}, {4=>"a", 5=>"b", 6=>"c"}, {7=>"a"}]

Merge all hashes withing the mapped array into a single hash

将映射数组中的所有散列合并到一个散列中

final = mapped.reduce Hash.new, :merge
=> {1=>"a", 2=>"b", 3=>"c", 4=>"a", 5=>"b", 6=>"c", 7=>"a"}

#3


0  

Here's a fun answer.

这是一个有趣的答案。

longer  = [1, 2, 3, 4, 5, 6, 7]
shorter = ['a', 'b', 'c']

h = Hash.new do |h,k|
  idx = longer.index(k)
  idx ? shorter[idx % shorter.size] : nil
end
  #=> {}

h[1] #=> a
h[2] #=> b
h[3] #=> c
h[4] #=> a
h[5] #=> b
h[6] #=> c
h[7] #=> a
h[8] #=> nil

h #=> {}

h.values_at(3,5) #=> ["c", "b"] 

If this is not good enough (e.g., if you wish to use Hash methods such as keys, key?, merge, to_a and so on), you could create the associated hash quite easily:

如果这还不够好(例如,如果您希望使用散列方法,如键,键?, merge, to_a等),您可以很容易地创建关联的散列:

longer.each { |n| h[n] = h[n] }
h #=> {1=>"a", 2=>"b", 3=>"c", 4=>"a", 5=>"b", 6=>"c", 7=>"a"}  

#1


7  

Here's an elegant one. You can "loop" the short array

这是一个优雅的人。您可以“循环”短数组

longer  = [1, 2, 3, 4, 5, 6, 7]
shorter = ['a', 'b', 'c']

longer.zip(shorter.cycle).to_h # => {1=>"a", 2=>"b", 3=>"c", 4=>"a", 5=>"b", 6=>"c", 7=>"a"}

#2


1  

A crude way until you find something more elegant: Slice the longer array as per length of shorter one, and iterate over it to re-map the values.

一种粗略的方法,直到您找到更优雅的方法:按较短数组的长度对较长的数组进行切片,并对其进行迭代以重新映射值。

mapped = longer.each_slice(shorter.length).to_a.map do |slice|
           Hash[slice.zip(shorter)]
         end
=> [{1=>"a", 2=>"b", 3=>"c"}, {4=>"a", 5=>"b", 6=>"c"}, {7=>"a"}]

Merge all hashes withing the mapped array into a single hash

将映射数组中的所有散列合并到一个散列中

final = mapped.reduce Hash.new, :merge
=> {1=>"a", 2=>"b", 3=>"c", 4=>"a", 5=>"b", 6=>"c", 7=>"a"}

#3


0  

Here's a fun answer.

这是一个有趣的答案。

longer  = [1, 2, 3, 4, 5, 6, 7]
shorter = ['a', 'b', 'c']

h = Hash.new do |h,k|
  idx = longer.index(k)
  idx ? shorter[idx % shorter.size] : nil
end
  #=> {}

h[1] #=> a
h[2] #=> b
h[3] #=> c
h[4] #=> a
h[5] #=> b
h[6] #=> c
h[7] #=> a
h[8] #=> nil

h #=> {}

h.values_at(3,5) #=> ["c", "b"] 

If this is not good enough (e.g., if you wish to use Hash methods such as keys, key?, merge, to_a and so on), you could create the associated hash quite easily:

如果这还不够好(例如,如果您希望使用散列方法,如键,键?, merge, to_a等),您可以很容易地创建关联的散列:

longer.each { |n| h[n] = h[n] }
h #=> {1=>"a", 2=>"b", 3=>"c", 4=>"a", 5=>"b", 6=>"c", 7=>"a"}