2009-11-25 27 views
14

Para dividir una matriz en dos trozos iguales Me gustaría hacer esto,RoR/Ruby eliminar elementos nulos de matriz anidada

>> a = [1,2,3,4,5] 
=> [1, 2, 3, 4, 5] 
>> a.in_groups_of((a.size/2.0).ceil) if a.size > 0 
=> [[1, 2, 3], [4, 5, nil]] 

ahora tengo una matriz anidada que contiene elementos nil si el tamaño de la matriz es impar. ¿Cómo puedo eliminar los elementos nil de las matrices anidadas? Quiero hacer algo así,

a.compact 

Pero, por desgracia que no funciona, rubí sólo elimina los elementos nulos en el primer nivel y no de forma recursiva. ¿Ruby proporciona alguna buena solución para este problema?

Respuesta

44

con Ruby 1.8.7 y más tarde se puede hacer lo siguiente:

a.each &:compact! 
=> [[1, 2, 3], [4, 5]] 

Con Ruby 1.8.6, tiene que hacer esto a lo largo:

a.each {|s| s.compact!} 

Ambos modificarán los contenidos de a. Si desea devolver una nueva matriz y dejar el solo original, puede utilizar collect en lugar de each:

# 1.8.7+: 
a.collect &:compact 

# 1.8.6: 
a.collect {|s| s.compact} 
+3

Pensé que la sintaxis & se introdujo en 1.8.7 – EmFi

+1

@EmFi Buen punto - Olvidé 1.8.7. Editaré mi respuesta. –

+0

También puede usar 'a.map (&: compact)' – Bongs

-3
a.each {|subarray| subarray.compact!} 
a.compact! 

En caso de trabajar ....

+2

Probablemente no vale la pena necro-posting, pero estas dos líneas deben estar en orden inverso. Si suponemos que 'a' tiene' nil's, entonces debemos * 'compact' primero *, de lo contrario obtendremos errores nil dentro del bloque. – NIA

3

A menos que desee cambiar de forma permanente un

a.map do |e| 
    e.compact 
end 
8

Si se va a utilizar el in_groups_of puede pasarlo false como el segundo argumento y no va a llenar en los "espacios en blanco" con nil, pero realmente nada.

0
arr_mixed=['hello', 2222, 'world', nil, [1, 2, 5, 'hi', nil],[1, 2, 3], [4, 5, nil]] 

def compact_nested(array) 
    arr2=[] 
    array.each { |x| 
    element = x.class==Array ? x.compact : x 
    arr2<<element 
    } 
    arr2 
end 

p compact_nested(arr_mixed).compact #=>["hello", 2222, "world", [1, 2, 5, "hi"], [1, 2, 3], [4, 5]] 
p arr_mixed #=>["hello", 2222, "world", nil, [1, 2, 5, "hi", nil], [1, 2, 3], [4, 5, nil]] 
Cuestiones relacionadas