将散列中的数据插入 Ruby 中设置索引处的数组
Insert data from hash into an array at set index in Ruby
我正在做 Ruby 任务,即“你有一组数字。你的任务是对奇数进行升序排序,但偶数必须在它们的位置上。零不是奇数,你不需要移动它。如果你有一个空数组,你需要 return 它。
决定拆分初始数组:将奇数推入另一个数组,对其进行排序,将偶数添加到哈希中,其中键为num,其初始索引为value。之后,尝试在偶数的初始索引处将偶数从散列插入奇数数组。因此,代码如下所示:
def sort_array(source_array)
even_nums = Hash.new
odd_nums = []
return source_array if source_array.length == 0
source_array.each_with_index {|n, ind| even_nums[n] = ind if n.even?}
source_array.select{|n| odd_nums.push(n) if n.odd?}
odd_nums.sort!
even_nums.each do |k, v|
odd_nums.insert(v, k)
end
odd_nums
end
对于 [5, 3, 2, 8, 1, 4, 11] 这样的小数组,它可以按预期工作,但是如果我传递更大的数组,比如 [84, -64, 40, 53, 5, 88, 2, 14, 29, -79, -44, -23, 20, -67, -12, 28, -28, -37, -27, -62, -54, 93, -61, 50, 65, -63, -62, 77, -16, 49, -43, 26, -73, -27, 88, -88, -62, 84, 54, 25, 25, -2, -99, 69, -23, 47, -92, 7, -62, -62, -58, -30, -75, -31, 65, -63, 16, 64, -7, -22, -6, -82]
我在排序数组的末尾得到 nils。像这样:
[-99, -64, 40, -79, -75, -73, 2, 14, -67, -63, -44, -63, 20, -61, -12, 28, -28, -43, -37, -31, -54, -27, -27, 50, -23, -23, -7, 5, -16, 7, 25, 26, 25, 29, 47, -88, 49, 53, 54, 65, 65, -2, 69, 77, 93, nil, -92, nil, nil, 88, -58, -30, nil, nil, nil, nil, 16, 64, nil, -22, -6, -82, 84, nil, -62]
难以理解,为什么它不适用于更大的数组?
如果您将其视为两个操作,则有一种相当简单的方法可以做到这一点:
def sort_array(arr)
# Extract and sort the odd values
odd = arr.select(&:odd?).sort
# Merge the sorted odd values back in
arr.map do |v|
v.odd? ? odd.shift : v
end
end
没什么大不了的。
你有一些正确的部分,但我认为当它开始变得过于复杂时你陷入了困境。
可以按如下方式完成。
def sort_odds(arr)
odd_pos = arr.each_index.select { |i| arr[i].odd? }
odd_pos.zip(odd_pos.sort_by { |i| arr[i] }).
each_with_object(arr.dup) do |(old_pos,new_pos),a|
a[new_pos] = arr[old_pos]
end
end
sort_odds [5, 3, 2, 8, 1, 4, 11]
# o o e e o e o
#=> [1, 3, 2, 8, 5, 4, 11]
步骤如下
arr = [5, 3, 2, 8, 1, 4, 11]
# o o e e o e o
odd_pos = arr.each_index.select { |i| arr[i].odd? }
#=> [0, 1, 4, 6]
new_pos = odd_pos.zip(odd_pos.sort_by { |i| arr[i] })
#=> [[0, 4], [1, 1], [4, 0], [6, 6]]
new_pos.each_with_object(arr.dup) do|(old_pos,new_pos),a|
a[new_pos] = arr[old_pos]
end
#=> [1, 3, 2, 8, 5, 4, 11]
我认为 比我的更简单、更优雅,但这也行得通。值得注意的是,此解决方案将允许您通过查找 evens 中的索引和值来验证偶数的位置(例如,在规范中)。除非您已经知道输出数组应该是什么样子,否则在调试中间结果时这可能很重要。
def odd_sorted array
odds = array.select { |e| e.odd? }.sort
evens = array.each_with_index.select { |e| e.first.even? }
arr2 = Array.new(array.size)
# put even numbers in at their previous index
evens.each do |e|
arr2.each_index { |i| arr2[i] = e[0] if e[1] == i }
end
arr2.each_with_index { |e, i| arr2[i] = odds.shift if e.nil? }
end
odd_sorted [5, 3, 2, 8, 1, 4, 11]
#=> [1, 3, 2, 8, 5, 4, 11]
odd_sorted [84, -64, 40, 53, 5, 88, 2, 14, 29, -79, -44, -23, 20]
#=> [84, -64, 40, -79, -23, 88, 2, 14, 5, 29, -44, 53, 20]
Array#map 解决方案肯定更优雅,但这(在我个人看来)更易于调试。你在这方面的里程肯定会有所不同。
我正在做 Ruby 任务,即“你有一组数字。你的任务是对奇数进行升序排序,但偶数必须在它们的位置上。零不是奇数,你不需要移动它。如果你有一个空数组,你需要 return 它。
决定拆分初始数组:将奇数推入另一个数组,对其进行排序,将偶数添加到哈希中,其中键为num,其初始索引为value。之后,尝试在偶数的初始索引处将偶数从散列插入奇数数组。因此,代码如下所示:
def sort_array(source_array)
even_nums = Hash.new
odd_nums = []
return source_array if source_array.length == 0
source_array.each_with_index {|n, ind| even_nums[n] = ind if n.even?}
source_array.select{|n| odd_nums.push(n) if n.odd?}
odd_nums.sort!
even_nums.each do |k, v|
odd_nums.insert(v, k)
end
odd_nums
end
对于 [5, 3, 2, 8, 1, 4, 11] 这样的小数组,它可以按预期工作,但是如果我传递更大的数组,比如 [84, -64, 40, 53, 5, 88, 2, 14, 29, -79, -44, -23, 20, -67, -12, 28, -28, -37, -27, -62, -54, 93, -61, 50, 65, -63, -62, 77, -16, 49, -43, 26, -73, -27, 88, -88, -62, 84, 54, 25, 25, -2, -99, 69, -23, 47, -92, 7, -62, -62, -58, -30, -75, -31, 65, -63, 16, 64, -7, -22, -6, -82]
我在排序数组的末尾得到 nils。像这样:
[-99, -64, 40, -79, -75, -73, 2, 14, -67, -63, -44, -63, 20, -61, -12, 28, -28, -43, -37, -31, -54, -27, -27, 50, -23, -23, -7, 5, -16, 7, 25, 26, 25, 29, 47, -88, 49, 53, 54, 65, 65, -2, 69, 77, 93, nil, -92, nil, nil, 88, -58, -30, nil, nil, nil, nil, 16, 64, nil, -22, -6, -82, 84, nil, -62]
难以理解,为什么它不适用于更大的数组?
如果您将其视为两个操作,则有一种相当简单的方法可以做到这一点:
def sort_array(arr)
# Extract and sort the odd values
odd = arr.select(&:odd?).sort
# Merge the sorted odd values back in
arr.map do |v|
v.odd? ? odd.shift : v
end
end
没什么大不了的。
你有一些正确的部分,但我认为当它开始变得过于复杂时你陷入了困境。
可以按如下方式完成。
def sort_odds(arr)
odd_pos = arr.each_index.select { |i| arr[i].odd? }
odd_pos.zip(odd_pos.sort_by { |i| arr[i] }).
each_with_object(arr.dup) do |(old_pos,new_pos),a|
a[new_pos] = arr[old_pos]
end
end
sort_odds [5, 3, 2, 8, 1, 4, 11]
# o o e e o e o
#=> [1, 3, 2, 8, 5, 4, 11]
步骤如下
arr = [5, 3, 2, 8, 1, 4, 11]
# o o e e o e o
odd_pos = arr.each_index.select { |i| arr[i].odd? }
#=> [0, 1, 4, 6]
new_pos = odd_pos.zip(odd_pos.sort_by { |i| arr[i] })
#=> [[0, 4], [1, 1], [4, 0], [6, 6]]
new_pos.each_with_object(arr.dup) do|(old_pos,new_pos),a|
a[new_pos] = arr[old_pos]
end
#=> [1, 3, 2, 8, 5, 4, 11]
我认为
def odd_sorted array
odds = array.select { |e| e.odd? }.sort
evens = array.each_with_index.select { |e| e.first.even? }
arr2 = Array.new(array.size)
# put even numbers in at their previous index
evens.each do |e|
arr2.each_index { |i| arr2[i] = e[0] if e[1] == i }
end
arr2.each_with_index { |e, i| arr2[i] = odds.shift if e.nil? }
end
odd_sorted [5, 3, 2, 8, 1, 4, 11]
#=> [1, 3, 2, 8, 5, 4, 11]
odd_sorted [84, -64, 40, 53, 5, 88, 2, 14, 29, -79, -44, -23, 20]
#=> [84, -64, 40, -79, -23, 88, 2, 14, 5, 29, -44, 53, 20]
Array#map 解决方案肯定更优雅,但这(在我个人看来)更易于调试。你在这方面的里程肯定会有所不同。