我有以下数组:
输入:
array = [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200]
输出:
array = [211, 200, 199, 198, 197, 196 ... ]
我已尝试each_with_index
但无法获得所需的结果。
答案 0 :(得分:2)
我不明白用nil
做什么,所以我没有解决这个问题。根据要求,arr
为array
或array.sort.reverse
。我想这是你想要的吗? (见我对这个问题的评论。)
def change_em(arr)
dup_indices = arr.each_index
.group_by { |i| arr[i] }
.values
.flat_map { |a| a.drop(1) }
puts "dup_indices = #{dup_indices}"
last = 0 # anything '-' responds to
arr.each_index.map { |i| last = dup_indices.include?(i) ? last-1 : arr[i] }
end
我已经包含puts
只是为了澄清我在这里做的事情。
change_em [10, 8, 5, 5, 7]
#=> dup_indices = [3]
#=> [10, 8, 5, 4, 7]
change_em [10, 8, 7, 5, 5]
#=> dup_indices = [4]
#=> [10, 8, 7, 5, 4]
change_em [10, 9, 9, 8, 8, 8]
#=> dup_indices = [2, 4, 5]
#=> [10, 9, 8, 8, 7, 6]
change_em [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 196]
#=> dup_indices = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
#=> [211, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 196]
注意声明
last = dup_indices.include?(i) ? last-1 : arr[i]
正在执行double-duty:它会更新last
的值并返回索引i
的映射值。另请注意,dup_indices
不能包含0
。
答案 1 :(得分:0)
写道这是一种更具功能性的风格。
def f(arr, dup_element = nil, dup_count = 0)
return generate_dup_array(dup_element, dup_count) if arr.empty?
if arr.head != arr.tail.head # Not duplicates
if dup_count == 0 # No duplicates to insert
[arr.head] + f(arr.tail)
else # There are duplicates to insert
generate_dup_array(dup_element, dup_count) + f(arr.tail)
end
else # Duplicate found, continue with tail of array and increase dup_count
f(arr.tail, arr.head, dup_count + 1)
end
end
def generate_dup_array(dup_element, dup_count)
return [] if dup_count == 0
(dup_element - dup_count..dup_element).to_a.reverse
end
class Array
def head; self.first; end
def tail; self[1..-1]; end
end
p f [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200]
# => [211, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190]
p f [10, 8, 5, 5, 7].sort.reverse
# => [10, 8, 7, 5, 4]
p f [9, 6, 6, 5, 5, 4, 4, 3, 3, 3, 2, 2, 1]
# => [9, 6, 5, 5, 4, 4, 3, 3, 2, 1, 2, 1, 1]
答案 2 :(得分:0)
不确定我是否完全理解您的要求,但这是我的尝试:
# Transforms an array of numbers into a sorted array of the same length, where
# each successive element is always smaller than the preceding element.
def force_descending(array)
array.sort.reverse.each_with_object([]) do |element, collection|
collection << if collection.empty? || element < collection.last
element
else
collection.last-1
end
end
end
示例输入/输出:
force_descending [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200]
#=> [211, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190]
force_descending [10, 8, 5, 5, 7]
#=> [10, 8, 7, 5, 4]
force_descending [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 196]
#=> [211, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189]
答案 3 :(得分:0)
它已经按降序排列
对于一线人群:
results = numbers.chunk {|num| num}.flat_map {|num, group| (group.length == 1) ? num : ((num - (group.length-1))..num).to_a.reverse}
对于理智的程序员:
numbers = [211, 200, 200, 200]
start_of_dups = "_START_" #Something not in the array
dup_count = 0
results = numbers.map do |num|
if start_of_dups == num
dup_count += 1
num - dup_count
else
dup_count = 0
start_of_dups = num
end
end
p results
--output:--
[211, 200, 199, 198]
但是如果:
array = [10, 10, 10, 9]
--output:--
[10, 9, 8, 9]