Ruby 从数组中按值排除第一个元素
我想得到这样的东西:Ruby 从数组中按值排除第一个元素,ruby,Ruby,我想得到这样的东西: a = [0,1,0,0,1,0,1,0] a.except(1) # => [0,0,0,1,0,1,0] a # => [0,1,0,0,1,0,1,0] a.except(1).except(1) # => [0,0,0,0,1,0] 如您所见,a的第一个元素等于的参数,但除外,它将从a中删除 我可以做到: tmp_a = a.dup tmp_
a = [0,1,0,0,1,0,1,0]
a.except(1) # => [0,0,0,1,0,1,0]
a # => [0,1,0,0,1,0,1,0]
a.except(1).except(1) # => [0,0,0,0,1,0]
如您所见,a
的第一个元素等于的参数,但
除外,它将从a
中删除
我可以做到:
tmp_a = a.dup
tmp_a.delete_at(a.index(1))
tmp_a
但在我看来,它看起来像气味。还有更优雅的单线解决方案吗?(换句话说,如何为数组定义方法“except”)
UPD
我很快就解决了这个问题
class Array
def except(elem)
dup.tap{|a| a.delete_at(a.index(elem))}
end
end
你觉得呢?你的解决方案有什么“黑”的地方
class Array
def except what, count = 1
memo = 0
map do |e|
what == e && (memo += 1) <= count ? nil : e
end.compact
end
end
这也是我第一次想到的(在阅读整个问题之前开始破解:p)
或者如果(包括我从@mudasobwa的答案中偷来的计数
),你可以使用delete\u的功能:
class Array
def except(elem, count = 1)
tmp = self.dup
memo = 0
tmp.delete_if { |e| elem == e && (memo += 1) <= count }
end
end
你可以写:
a.difference [1]
#=> [0,0,0,1,0,1,0]
a #=> [0,1,0,0,1,0,1,0]
在我的答案中定义了Array#difference
。编写一个封装元素查找和切片的方法。没有理由复制数组,只需将元素放在值的两边。Meta-comment:由于误解而导致答案变得枯燥对我来说似乎是极端的,只需注释以澄清,用户将监督他们的行为自己的内容。我没有投否决票,但是,在“否决票”按钮的工具提示中提到的否决票的可能原因之一是“这个问题不清楚”,因此,如果一个用户觉得问题不清楚,那么向下投票是完全可以的。即使一个用户碰巧弄错了,那么,还有410万其他用户可以向上投票。这个问题有什么不清楚的地方?Gena,我喜欢你使用点击,所以修改了我的代码为Array#difference
(在我回答中给出的链接处)使用tap
代替cpy=dup
,然后将cpy
作为最后一行。我非常喜欢这个方法的声音,以至于有时我会写obj.tap{}.tap{}.tap{}.tap{x}
。投票赞成切片
(我会重写为self[0…index]+self[index+1..-1]
)。您可以将slice
调用替换为:reject.with_index{| | | i==index}
如果解决方案,这将与delete\u相同。@Manuel谢谢,它看起来不错。在问题中的UPD下查看我自己的解决方案啊,非常有趣!不知道点击!但是,我实际上更喜欢你的第一个版本,因为它更可读。从技术上讲,它是相同的解决方案。很酷的解决方案,但请注意你的数组看起来是这样的:[0,nil,0,0,nil,0,nil,0]
。但是,不管怎样,谁的数组中有nil
s…这与我在UPD下的解决方案相同,很酷,谢谢当difference
的参数是一个包含单个元素的数组时,是的。
class Array
def except(elem, count = 1)
tmp = self.dup
memo = 0
tmp.delete_if { |e| elem == e && (memo += 1) <= count }
end
end
class Array
def except(elem)
index = self.index(elem)
self.slice(0, index) + self.slice(index + 1, self.length)
end
end
a.difference [1]
#=> [0,0,0,1,0,1,0]
a #=> [0,1,0,0,1,0,1,0]