问题描述
使用Ruby .uniq方法甚至.to_set时,如何移动数组的顺序或保持数组的自然顺序?
例如:
([3,4,3,6,3]) # => [4,3])
### with current method my solution outputs:
Expected: [4,3],instead got: [3,6]
这些是我到目前为止尝试过的所有其他方法:
def solve arr
#arr.each do |charas| arr << charas unless arr.include?(charas)
#end
arr.to_set.to_a
# arr.uniq
# arr & arr
# arr.to_set
end
示例测试:
(solve([3,3]),[4,3])
Test.assert_equals(solve([1,2,1,[1,4]),4])
Test.assert_equals(solve([1,5,1]),1])
解决方法
在reverse
之前和之后两次使用uniq
。这是:reverse.uniq
按原始数组中从最后一个到第一个出现的顺序返回唯一元素。第二个reverse
将这些元素按在输入数组中找到的顺序放置:
my_array.reverse.uniq.reverse
例如:
puts [3,4,3,6,3].reverse.uniq.reverse.inspect # => [4,3]
puts [1,2,1,3].reverse.uniq.reverse.inspect # => [1,4].reverse.uniq.reverse.inspect # => [1,4]
puts [1,5,1].reverse.uniq.reverse.inspect # => [4,1]
,
您似乎想要按Array
中的最后一个索引排序的唯一元素。
我们可以使用uniq
,sort_by
和rindex
(它们将返回给定元素的最后一个索引)来处理此问题
arr = [3,3]
arr.uniq.sort_by(&arr.method(:rindex))
#=> [4,3]
,
我对问题的理解是,如果arr
是给定的数组,我们将生成一个包含brr
唯一元素的数组arr
,该元素具有以下属性:对于任何两个索引i
和j
,0 <= i < j <= brr.size-1
,arr.rindex(brr[i]) < arr.rindex(brr[j]
。内容为:“ brr[i]
中arr
的最后一个实例在brr[j]
中arr
的最后一个实例之前。
这是一种通过一遍生成所需数组的方法。
require 'set'
def weird_uniq(arr)
set = Set.new
h = arr.reverse_each.with_object([]) { |n,a| a.unshift(n) if set.add?(n) }
end
weird_uniq [3,3]
#=> [4,3])
weird_uniq [1,3]
#=> [1,3]
weird_uniq [1,4]
#=> [1,4]
weird_uniq [1,1]
#=> [4,1]
请参见Set#add?。像哈希键查找一样,集合查找非常快,几乎与集合的大小无关。
,您期望什么顺序?您要按他们的上一个索引排列数字吗?
def solve arr
#arr.each do |charas| arr << charas unless arr.include?(charas)
#end
arr.each_with_object([]) do |element,arr|
if arr.include?(element)
arr.delete(element)
arr<<element
else
arr<<element
end
end
end
p solve([3,3]) # => [4,3])
,
我不确定您希望如何获得显示的订单。您的问题中可能没有包含代码。无论如何,在Ruby 2.7.1上,Array#uniq当然似乎保留了原始顺序:
[3,3].uniq
#=> [3,6]
如果您想做一些不同的事情,逻辑方法可能是使用Enumerable#each_with_index遍历数组,使用索引以您认为合适的方式管理元素的顺序。