24

我有一个项目数组,我需要删除它的前 x 个项目。Ruby Array 类中是否有内置函数来执行此操作?我四处搜索,只发现了看起来非常混乱或效率低下的方法。

我最好喜欢这样的东西:

my_items = [ 'item1', 'item2', 'item3', 'item4' ]
trimmed_items = my_items.delete(y, x) # deleting x entries from index y
4

4 回答 4

56

我有一个项目数组,我需要删除它的前 x 个项目。

无损删除

Array#drop(x) 将为您完成工作。

从 ary 中删除前 n 个元素并返回数组中的其余元素。如果给出负数,则引发 ArgumentError。

my_items = [ 'item1', 'item2', 'item3', 'item4' ]
p my_items.drop(2)
p my_items

# >>["item3", "item4"]
# >>["item1", "item2", "item3", "item4"]

破坏性删除

Array#shift

删除 self 的第一个元素并返回它(将所有其他元素向下移动一个)。如果数组为空,则返回 nil。如果给定数字 n,则返回前 n 个元素(或更少)的数组,就像 array.slice!(0, n) 一样。

my_items = [ 'item1', 'item2', 'item3', 'item4' ]
my_items.shift(2)
p my_items # => ["item3", "item4"]
于 2013-07-22T14:09:41.720 回答
4

实现此目的的另一种方法是: use Array#shift,当您想要从数组前面删除的值时,这特别有用。

a = (1..5).to_a
a.shift(2)
a # => [3, 4, 5]
于 2013-07-22T14:26:03.577 回答
3

要进行破坏性更新my_items,您可以执行以下操作:

my_items.slice!(0, 2)
# => ["item1", "item2"] 
my_items
# => ["item3", "item4"] 
于 2013-07-22T14:11:04.383 回答
1

为了完整起见,我将添加另一种方法来实现“删除数组的前 x 个条目”并在不影响原始数组的情况下获取数组的剩余元素,这就是 Enumerable 模块中的 drop 的工作原理:

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

事实上, [] 是切片的别名,如 Array 文档中所指定:

ary[index] → obj or nil
ary[start, length] → new_ary or nil
ary[range] → new_ary or nil
slice(index) → obj or nil
slice(start, length) → new_ary or nil
slice(range) → new_ary or nil

既然我做出了贡献,我想说我更喜欢 drop and shift。

由于 drop 是 Enumerable 的实例方法,因此它可以应用于类实现 Enumerable 模块的任何对象,包括 Array 和 Hash。因此,它是在 Enumerable 对象上调用的。但是,drop 返回数组的剩余元素。因此它会删除指定的元素并返回其余元素:

[1,2,3,4,5].drop(2)
 => [3, 4, 5] 
{a: 'a', b: 'b', c: 'c'}.drop(2)
 => [[:c, "c"]] 

请注意,无论 Enumerable 对象如何,返回值都是 Array 中的剩余元素。正如答案已经指出的那样,原始对象没有发生变异。

shift 方法在 Array 中实现,不是 Enumerable 对象,因此只能应用于 Arrays。Shift 返回从数组中删除的元素,并且由于它改变了数组本身,您仍然可以通过保存数组的变量访问剩余的元素:

arr = [1,2,3,4,5]
 => [1, 2, 3, 4, 5] 
arr.shift(2)
 => [1, 2] 
arr
 => [3, 4, 5] 

最终,有很多方法可以做到这一点,这取决于您在响应中想要什么以及您是否介意数组是否发生了突变。

于 2018-10-12T23:34:25.800 回答