Ruby 数组中除最后一个元素外的所有元素

假设我有一个 Ruby 数组

a = [1, 2, 3, 4]

如果我想要所有,但第一个项目,我可以写 a.drop(1),这是伟大的。但是,如果我想要除 最后之外的所有项目,我只能这样想

a[0..-2]   # or
a[0...-1]

但是这些都不如使用 drop干净。还有其他内置的方法我没有注意到吗?

113366 次浏览

也许..。

a = t               # => [1, 2, 3, 4]
a.first a.size - 1  # => [1, 2, 3]

或者

a.take 3

或者

a.first 3

或者

a.pop

它将返回最后一个,并将数组保留在它之前的所有内容

或者让电脑为它的晚餐工作:

a.reverse.drop(1).reverse

或者

class Array
def clip n=1
take size - n
end
end
a          # => [1, 2, 3, 4]
a.clip     # => [1, 2, 3]
a = a + a  # => [1, 2, 3, 4, 1, 2, 3, 4]
a.clip 2   # => [1, 2, 3, 4, 1, 2]

你有没有试过

a.take(3)

出于好奇,你为什么不喜欢 a[0...-1]?您希望获取数组的一个切片,因此切片运算符似乎是惯用的选择。

但是如果您需要到处调用它,您总是可以选择向 Array 类添加一个名称更友好的方法,就像 DigitalRoss 建议的那样。也许像这样:

class Array
def drop_last
self[0...-1]
end
end

a[0...-1]似乎是最好的方法。数组切片语法正是为此目的而创建的..。

或者,如果您不介意就地修改数组,您可以直接调用 a.pop:

>> a = [1, 2, 3, 4]
>> a.pop
>> a
=> [1, 2, 3]

例如,如何增加 drop 方法本身?

class Array
def drop(n)
n < 0 ? self[0...n] : super
end
end

然后你可以使用一个负的大小从末端删除元素,像这样:

[1, 2, 3, 4].drop(-1) #=> [1, 2, 3]
[1, 2, 3, 4].drop(-2) #=> [1, 2]

这会创建一个新数组,其中除了原始数组的最后一个元素外,其他元素都包含在内:

ary2 = ary.dup
ary2.pop

请注意,还有一些人建议使用 # pop。如果可以在适当的位置修改数组,那就可以了。如果您对此不满意,那么首先添加数组,如本例所示。

又一个很酷的把戏

>> *a, b = [1,2,3]
=> [1, 2, 3]
>> a
=> [1, 2]
>> b
=> 3

答: a.τwτ,但是您必须先安装 派珀..。

你知道 Lispy carcdr返回数组的“ first”和“ rest”吗?为了满足你的需要,我扩展了 Lispy 机制。它叫做 pyper,它允许你访问第二层,第二层休息,第三层休息,第三层休息,还有最后一层,除了最后一层以外的所有东西。这没什么可写的,但是它也允许字母组合,就像 caarcadrcdadar等等 Lisp 中已知的:

# First, gem install pyper
require 'pyper'
include Pyper
a = %w/lorem ipsum dolor sit amet/
# To avoid confusion with other methods, and also because it resembles a rain gutter,
# Greek letter τ is used to delimit Pyper methods:
a.τaτ #=> "lorem"
a.τdτ #=> ["ipsum", "dolor", "sit", "amet"]
a.τbτ #=> "ipsum"
a.τeτ #=> ["dolor", "sit", "amet"]
a.τcτ #=> "dolor" (3rd)
a.τzτ #=> "amet" (last)
a.τyτ #=> "sit" (2nd from the end)
a.τxτ #=> "dolor" (3rd from the end)

最后,回答你的问题:

a.τwτ #=> ["lorem", "ipsum", "dolor", "sit"] (all except last)

还有更多:

a.τuτ #=> ["lorem", "ipsum", "dolor"] (all except last 2)
a.τ1τ #=> ["lorem", "ipsum"] (first 2)
a.τ8τ #=> (last 2)
a.τ7τ #=> (last 3)

作品:

a.τwydτ #=> "olor" (all except 1st letter of the last word of all-except-last array)

除了 a..fu..z0..9,还有更多的命令字符,最著名的是 m,意思是地图:

a.τwmbτ #=> ["o", "p", "o", "i"] (second letters of all-except-last array)

但是其他命令字符太热,目前不太容易使用。

去掉一行中的最后一个元素,并返回剩余的元素

[1, 2, 4, 5, 6].reverse.drop(1).reverse

说真的,

[1,2,3,4][0..-2]
#=> [1,2,3]

我经常发现自己需要数组中除最后 n 个元素以外的所有元素。我设计了自己的函数来实现这一点,我发现这种方法比其他解决方案更具可读性:

class Array
def all_but_the_last(n)
self.first(self.size - n)
end
end

现在你可以做以下事情:

arr = ["One", "Two", "Three", "Four", "Five"]
# => ["One", "Two", "Three", "Four", "Five"]


arr.all_but_the_last(1)
# => ["One", "Two", "Three", "Four"]


arr.all_but_the_last(3)
# => ["One", "Two"]


arr.all_but_the_last(5)
# => []


arr.all_but_the_last(6)
# ArgumentError: negative array size

我特意允许使用 ArgumentError,以便调用方对如何使用此方法负责。我希望听到对这种方法的评论/批评。

a = [1,2,3,4]


a[0..(a.length - 2)]
=> [1,2,3]

如果您想对数组执行 pop()操作(这将导致最后一项被删除) ,但您感兴趣的是获取数组而不是弹出元素,您可以使用 tap(&:pop):

> arr = [1, 2, 3, 4, 5]
> arr.pop
=> 5
> arr
=> [1, 2, 3, 4]
> arr.tap(&:pop)
=> [1, 2, 3]

这就是办法:

[1,2,3,4,5][0..-1-1]

但是让我们来解释一下这是如何运作的:

a = [1,2,3,4,5]

下一个示例将返回所有记录 从0位置到最后

a[0..-1]
=> [1, 2, 3, 4, 5]

下一个例子将返回记录 从一个位置到最后一个位置

a[1..-1]
=> [2, 3, 4, 5]

这里你有你需要的。下一个例子将返回记录 从0位置到最后 -1位置

a[0..-1-1]
=> [1, 2, 3, 4]

我是这样做的:

my_array[0..-2]