提问人:oj5th 提问时间:4/14/2023 最后编辑:Mark Rotteveeloj5th 更新时间:5/10/2023 访问量:138
使用 Ruby 仅删除数组中的特定重复项
Remove only specific duplicates in array using Ruby
问:
有没有办法使用 Ruby 删除数组中的特定重复项?数组示例:
["hello", "removeme", "removeme", "hello", "testing"]
我只想删除该数组上的重复项。所需的输出为:"removeme"
["hello", "removeme", "hello", "testing"]
有没有这样的方法来获得所需的输出?["hello", "removeme", "removeme", "hello", "testing"].uniq('removeme')
答:
可以使用以下方法。
def removem(arr, to_remove)
i = arr.index(to_remove)
i.nil? ? arr : (arr - [to_remove]).insert(i, to_remove)
end
假设给定的数组如下所示。
arr = ["hello", "removeme", "hello", "goodbye", "removeme", "testing"]
然后
removem(arr, "removeme")
#=> ["hello", "hello", "goodbye", "testing", "removeme"]
removem(arr, "goodbye")
#=> ["hello", "removeme", "hello", "goodbye", "removeme", "testing"]
removem(arr, "missing")
#=> ["hello", "removeme", "hello", "goodbye", "removeme", "testing"]
在每个示例中都保持不变。arr
参见 Array#index 和 Array#insert
像这样拒绝除第一次出现这个词之外的所有内容怎么样?
def uniq_word(array, word)
return array unless first = array.index(word)
array.reject.with_index { |elem, index| index > first && elem == word }
end
array = ["hello", "removeme", "removeme", "hello", "testing"]
uniq_word(array, 'removeme')
#=> ["hello", "removeme", "hello", "testing"]
请参阅 Array#index、Enumerator#with_index
和 Array#
reject
。
或者,您可以迭代 aray 并仅将第一次出现复制到新数组中:
def uniq_word(array, word)
found = false
[].tap do |result|
array.each do |elem|
if elem == word && !found
found = true
next
end
result << elem
end
end
end
array = ["hello", "removeme", "removeme", "hello", "testing"]
uniq_word(array, 'removeme')
#=> ["hello", "removeme", "hello", "testing"]
看:
您可以将 uniq
与块一起使用,该块会根据块的返回值删除重复项:
ary = ["hello", "removeme", "removeme", "hello", "testing"]
ary.uniq { |obj| obj.eql?('removeme') || Object.new }
#=> ["hello", "removeme", "hello", "testing"]
对于等于我们返回的元素,对于其他所有元素(、 和 ),我们返回一个新对象:(注意不同的对象 ID)'removeme'
true
'hello'
'hello'
'testing'
"hello" → #<Object:0x00007f9ab08590d8>
"removeme" → true
"removeme" → true
"hello" → #<Object:0x00007f9ab0858d68>
"testing" → #<Object:0x00007f9ab08589f8>
所有具有相同返回值的元素都被视为重复元素,即 将被视为副本,而将任何其他内容视为唯一,无论其实际值如何。这允许保留两个相同的字符串。uniq
'removeme'
'hello'
除了 ,您还可以使用元素的索引:Object.new
ary.enum_for(:uniq).with_index { |obj, i| obj.eql?('removeme') || i }
#=> ["hello", "removeme", "hello", "testing"]
enum_for
是必需的,因为如果没有块,则返回一个新数组而不是枚举器(而枚举器又需要枚举器来链接with_index
)。uniq
评论
n = 0; ary.uniq { |obj| obj.eql?('removeme') || n += 1 }
通过添加新方法来扩展 Array 类怎么样?
class Array
def uniq_specific!(targets)
found = {}
targets.each { |target| found[target] = false }
delete_if do |item|
if targets.include?(item)
if found[item]
true
else
found[item] = true
false
end
else
false
end
end
end
end
array = ["hello", "removeme", "removeme", "hello", "world", "world", "testing"]
array.uniq_specific!(["removeme", "hello"])
array # => ["removeme", "hello", "world", "world", "testing"]
我们定义了一个新方法uniq_specific!用于接受目标元素数组作为参数的 Array 类。它遍历数组并删除每个目标元素的所有匹配项,但第一个元素除外。然后,我们在目标值为 [“removeme”, “hello”] 的示例数组上调用此方法,从而产生所需的输出。
评论
"hello"
"removeme"
Array
评论
["hello", "removeme", "hello", "testing", "removeme"]
"removeme"
["hello", "removeme", "hello", "testing"]
removeme
uniq
hello
removeme
["hello", "removeme", "hello", "testing"]