2014-01-21 4 views

ответ

2

Я хотел бы сделать, как показано ниже:

a = ['foo', [nil], 'baz', ['bar'], nil, ['zoo']] 
a.map { |e| e.is_a?(Array) ? e.compact : e }.compact 
# => ['foo', [], 'baz', ['bar'], ['zoo']] 

Update:

a.map { |e| e.instance_of?(Array) ? e.compact : e }.compact 

более чистый instance_of?, возвращает true, если объект является экземпляром этого точного класса, не подкласс.

+0

да, это похоже на 'a.map! {| V | (v.compact, если v.is_a? Array) || v} .compact', но 'is_a?' неясно. есть другие мысли? –

+0

@Monk_Code я изменил .. более ясно '#instance_of?' :) –

+0

@ArupRakshit no, более ясно предыдущая версия =) –

4

Попробуйте код:

array = ['foo', [nil], 'baz', ['bar'], nil, ['zoo']] 
array.map! {|v| v.is_a?(Array) && v.compact || v }.compact 
# => ["foo", [], "baz", ["bar"], ["zoo"]] 

или более гибкий:

array.map! {|v| v.respond_to?(:compact) && v.compact || v }.compact 
# => ["foo", [], "baz", ["bar"], ["zoo"]] 

или с ловушкой:

array.map! {|v| v.compact rescue v }.compact 
# => ["foo", [], "baz", ["bar"], ["zoo"]] 
+2

Я не знаю, сколько людей полагается на * инлайн спасения * .. Существует риск. –

+0

@ArupRakshit, какой риск? –

2

А вот рекурсивная версия, которая работает с более глубокой вложенностью:

a = ['foo', [nil, [nil, nil, [nil, 1, 2]]], 'baz', ['bar'], nil, ['zoo']] 

def recursive_conpact(arr) 
    arr.is_a?(Array) ? arr.compact.map{|x|recursive_conpact(x)} : arr 
end 

p recursive_conpact(a) #=> ["foo", [[[1, 2]]], "baz", ["bar"], ["zoo"]] 
Смежные вопросы