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

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

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

amindfv
источник
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если это массив.
Эрик