2009-10-21 2 views
109

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

a = [1, 2, 3, 4] 

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

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

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

+0

Согласно протоколу HTTP: // www.globalnerdy.com/2008/07/10/enumerating-enumerable-enumerabledrop/, падение - ruby ​​1.9, а не рубин 1.8.6 –

+0

Что касается исполнителя ce .. Если бы я использовал эти ответы в итерациях в течение 1000 раз ..., которые выиграли бы? – Ninad

+0

Другими словами, какое решение не пересекает массив под капотом? – Ninad

ответ

100

Возможно ...

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] 
+5

Добавление метода к 'Array' кажется лучшим для меня. Большинство проектов заканчиваются файлом 'core_ext.rb' с небольшими расширениями вроде этого. В некоторых библиотеках есть практически _all_ расширения, например: «ActiveSupport». – rfunduk

+0

Это интересно, я задавался вопросом, насколько это распространено. Что люди думают о стихотворном режиме? – DigitalRoss

+3

Как кто-то передает этот метод 'clip' в сообщество Ruby? Я действительно думаю, что это должно быть там, и исправление обезьян - это [Неверная вещь] (http://www.catb.org/jargon/html/W/Wrong-Thing.html). – Droogans

6

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

a.take(3) 
+5

В общем, это 'a.take (a.size - 1)'; да, я рассмотрел этот вариант. – Peter

75

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

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

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

это просто кажется большим количеством беспорядка, когда падение настолько чистое. это неважно, но трудно сразу напомнить, что это точно. Я предпочитаю ваше имя, 'drop_last', кстати ... – Peter

+0

Мне нравится использовать -1 настолько элегантнее, чем использовать .length –

+0

Это лучшее решение пока – LowFieldTheory

18

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

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

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

вы также можете назначить последний элемент переменной для последующего использования: 'b = a.pop' –

22

Как насчет увеличения капельного метода например, как это?

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] 
+0

Отличный ответ. Это добавит синтаксис Ruby. – joelparkerhenderson

1

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

ary2 = ary.dup 
ary2.pop 

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

+1

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

+0

Это важный комментарий. Вы можете просто добавить его к своему ответу. Так как #pop не имеет bang (!), То факт, что он изменяет исходный массив, может уйти от людей. – mjnissim

45

Еще один крутой трюк

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

Ницца, не знал, что у Руби это было; поэтому 'a, * b = [1,2,3]' позволит нам посмотреть на массив в классическом стиле car/cdr. – AndrewK

+0

'a, * b = [1,2,3]' эквивалентно 'a, b = [1,2,3]', оба результата приводят к 'a = [1]; b = [2,3] ' –

+0

Приятно! Функциональное программирование! – Prodis

0

Ответ:a.τwτ, но вы должны установить Pyper первый ...

интро Пайпер: Вы знаете 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, то есть карта:

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

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

+0

Я читаю это 1 апреля, поэтому предположил, что это шутка ... нет. Не думал, что этот материал существует для Руби. :) –

9

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

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

серьезно,

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

этот ход кажется вроде как трюк с скейтбордом или чем-то –

1

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

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

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

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

Не работает, когда a = [1] a [0 ..- 1] = [1] –

26

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

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

Этот ответ является тем, что семантически имеет смысл для этого пользователь. Операции с зеркалом под рукой, и они используют слова, которые легко интерпретировать && краткие. – Jerome

9

Это путь:

[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] 
+0

Вы можете написать '-2' вместо' -1-1'. – bfontaine

+2

Да, я оставил -1-1, чтобы объяснить концепцию –

18

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

my_array[0..-2] 
+0

Это работает фантастически. Я смущен, почему существует множество более сложных ответов. Это новое дополнение Ruby? –

0

Попробуйте

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

Смежные вопросы