Создать или добавить в массив в Ruby


85
foo ||= []
foo << :element

Немного неуклюжий. Есть ли способ более идиоматичный?


11
Это является идиоматическим способом. Вы можете однострочить это как (foo ||= []) << :element, но я считаю это уродливее.
Серджио Тюленцев

4
ИМО правильный способ - иметь начальные значения. Если у вас есть || = и << для одной и той же переменной в одном методе, у вас, IMO, есть запах кода и вы уже сделали что-то не так. Спрашивать, как сделать || = << красиво, значит делать косметику, а не решать настоящую проблему.
apeiros

Ответы:


142
(foo ||= []) << :element

Но м-м-м. Неужели сохранять его читабельным настолько обременительно?


40
+1 за «Неужели держать его в удобочитаемом состоянии так обременительно?» Читаемость - это король.
Железный Человек

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

60

Вы всегда можете использовать метод push и для любого массива. Мне это больше нравится.

(a ||= []).push(:element)

10

Вы также можете воспользоваться массивом Kernel # Array , например:

# foo = nil
foo = Array(foo).push(:element)
# => [:element]

который имеет преимущество сглаживания потенциального массива, например:

# foo = [1]
foo = Array(foo).push(:element)
# => [1, :element]

Я не уверен , что она всегда будет гарантирована в Ruby , который foo = fooустанавливает fooв nilкогда fooне определен. Кроме того, Kernel#Arrayне сглаживается foo. Он просто возвращается, fooесли это массив.
Эрик
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.