Подтвердить что ты не робот

Идиоматический фильтр Ruby для nil-or-empty?

Я ищу более идиоматический способ фильтрации нулевых или пустых элементов массива.

У меня есть много методов вида:

def joined
    [some_method, some_other_method].compact.reject(&:empty?).join(' - ')
end

Это приведет к результатам some_method и some_other_method и вернет только одно (-ы), которые не являются нильскими (compact по существу эквивалентными reject(&:nil?)) и непустыми.

Есть ли что-нибудь в массиве или Перечислении, которое получает одно и то же за один снимок?

4b9b3361

Ответ 1

В Rails вы можете сделать reject(&:blank?) или, что то же самое, select(&:present?).

Если это не для приложения Rails, и вы делаете это много, я бы посоветовал вам определить свой собственный помощник на String или что бы вы ни фильтровали.

class String
  alias :blank? :empty?
end

class NilClass
  def blank?
    true
  end
end

Ответ 2

Следующий код должен сделать трюк:

[some_method, some_other_method].reject{|i| i.nil? || i.empty? }

Его можно легко использовать для расширения класса массива:

class Array

  def purge
    self.reject{|i| i.nil? || i.empty? }
  end 

end

И тогда вы можете просто сделать:

[some_method, some_other_method].purge

Ответ 3

Обезьянчатые передачи приняты?:)

вы можете попробовать следующее:

class Array
  def tight
    self.compact.reject { |i| i.size.zero? }
  end
end

p [nil, 1, ''].tight
#=> [1]
p ['', nil, 2].tight
#=> [2]

он будет работать с любыми объектами, которые отвечают на size, а не только на те, которые отвечают на empty?

Ответ 4

Возможно, нам нужно только одно простое расширение для NilClass?

class NilClass
  def empty?
    true
  end
end

Ответ 5

@trans наслаждался моим +1, но после дальнейшего обсуждения я пришел к следующему выводу.

Если мы исходим из предпосылки, что все есть Object, тогда нам действительно нужен патч для class Object

class Object
    def empty?
        self == 0 or not self
    end
end

Что удовлетворяет моему требованию:

1.9.3 :001 > d=[Object.new, Class, {a:nil}, 'a', '', [], 1, 1.1, 0, 0.0, 0x0, 0E0, true, false, nil]
 => [#<Object:0x007fd56c086918>, Class, {:a=>nil}, "a", "", [], 1, 1.1, 0, 0.0, 0, 0.0, true, false, nil] 
1.9.3 :002 > d.reject(&:empty?)
 => [#<Object:0x007fd56c086918>, Class, {:a=>nil}, "a", 1, 1.1, true] 

Как насчет вашего? Нам нужно что-то еще? Пожалуйста, сообщите о своих проблемах или покажите молчаливое согласие путем голосования, чтобы помочь мотивировать изменение языка вверх по течению.

NJoy!

Ответ 6

Я думаю, вам не нужно использовать метод reject. Просто используйте метод Array select.

def joined
  [some_method, some_other_method].select { |method| method.present? }
end

Или даже лучше:

def joined
  [some_method, some_other_method].select(&:present?)
end

Для более Идиоматический способ записи кода Ruby, вы должны прочитать это статья