Все, кроме последнего элемента массива Ruby

Скажем, у меня есть массив Ruby

a = [1, 2, 3, 4]

Если мне нужен все, кроме первого элемента, я могу написать a.drop(1), что здорово. Если я хочу все, кроме последнего элемента, я могу думать только об этом.

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

но ни один из них не кажется таким же чистым, как использование drop. Любые другие встроенные способы, которые мне не хватает?

Ответ 1

Возможно...

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]

Ответ 2

Из любопытства, почему вам не нравится a[0...-1]? Вы хотите получить кусочек массива, поэтому оператор среза выглядит как идиоматический выбор.

Но если вам нужно называть это повсюду, у вас всегда есть возможность добавить метод с более дружественным именем в класс Array, например, предложенный DigitalRoss. Возможно, вот так:

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

Ответ 3

Еще один классный трюк

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

Ответ 4

Если вы хотите выполнить операцию pop() в массиве (который приведет к удалению последнего элемента), но вы заинтересованы в получении массива вместо выскоченного элемента, вы можете использовать tap(&:pop)

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

Ответ 5

Как насчет расширения самого метода 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]

Ответ 6

a[0...-1] кажется лучшим. Синтаксис разрезания массива был создан именно для этой цели...

В качестве альтернативы, если вы не возражаете изменить массив на месте, вы можете просто вызвать a.pop:

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

Ответ 7

Я делаю это так:

my_array[0..-2]

Ответ 8

Это способ:

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

Но объясните, как это работает:

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

В следующем примере будут возвращены все записи, от 0 до последней

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

Следующий пример вернет записи из 1 позиции в конец

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

И здесь у вас есть то, что вам нужно. Следующий пример вернет записи из 0 позиции в последний-1

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

Ответ 9

Вы пробовали "взять"

a.take(3) 

Ответ 10

Чтобы избавиться от последнего элемента в одной строке с остатком, возвращающим

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

Серьезно, однако,

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

Ответ 11

Это создает новый массив со всеми, кроме последних элементов оригинала:

ary2 = ary.dup
ary2.pop

Обратите внимание, что некоторые другие предложили использовать #pop. Если вы хорошо модифицируете массив на месте, это прекрасно. Если вы не в порядке с этим, тогда сначала сверните массив, как в этом примере.

Ответ 12

Я часто обнаруживаю, что хочу всех, кроме последних 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, чтобы вызывающий отвечал за то, как они используют этот метод. Я хотел бы услышать комментарии/критические замечания по этому подходу.

Ответ 13

Ответ: a.τwτ, но вам нужно сначала установить Pyper...

Pyper intro: Знаете ли вы, что Lispy car и cdr возвращают "первый" и "остаток" массива? Только для таких потребностей, как ваш, я сделал расширение этого механизма Lispy. Он называется pyper, и он позволяет вам получить доступ также к 2-му, отдохнуть от 2-го, 3-го, отдохнуть от 3d, а также последнему, все, кроме последнего и т.д. Это было бы не так много, чтобы писать, но также позволяет составлять букву, так же, как caar, cadr, cdadar и т.д., известные из 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..f, u..z и 0..9, наиболее заметно m, что означает map:

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

Но другие командные символы слишком горячие и не очень удобные в данный момент.

Ответ 14

Попробуйте это

arr = [1, 2, 3, 4, 5, 6] arr.delete(arr[-1])

Ответ 15

a = [1,2,3,4]

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