objetos metodos length instanciar como atributo arreglos arreglo array arrays ruby sorting heterogeneous-array

arrays - metodos - Ordenar una matriz según un atributo que puede ser nulo en algunos elementos



length java arreglos (3)

Tengo una matriz de objetos

[<#a star=1 val=1>, <#a star=nil val=3> , <#a star=2 val=2>]

Necesito que la matriz se ordene por tiempo, luego por val

[ <#a star=2 val=2>, <#a star=1 val=1>, <#a star=nil val=3> ]

pero el uso de sort_by lanza un error porque el tiempo es nulo.

Estoy usando una forma fea de ordenar ahora, pero estoy seguro de que hay una buena manera de hacerlo

starred=[] @answers.each {|a| (starred << a) if a.starred } @answers=@answers-starred starred=starred.sort_by {|a| a.starred }.reverse @answers=starred+@answers


Si quieres que los nils aparezcan primero (equivalente a cero):

@answers.sort_by { |a| a.star or 0 }

Si desea que aparezcan en último lugar, puede reemplazar el cero con un Int. Máx., Pero se siente demasiado intrépido. Esto podría ser mejor:

@answers.select(&:starred?).sort_by(&:star) + @answers.reject(&:starred?)

La respuesta provista por Nakilon es brillante, aunque básicamente estás clasificando dos veces, en dos atributos diferentes. Para la mayoría de las situaciones es probable que sea suficiente.


Solo usa value.to_i

starred.sort_by { |a| a.to_i }.reverse


starred.sort_by { |a| [a ? 1 : 0, a] }

Cuando tiene que comparar dos elementos, compara una matriz. Cuando Ruby compara arrays (llama al método === ), compara el 1er elemento y va a los 2dos elementos solo si el 1er es igual. ? 1 : 0 Garantías de ? 1 : 0 , que tendremos Fixnum como primer elemento, por lo que no debería haber ningún error.

Si tu lo haces ? 0 : 1 , nil aparecerá al final de la matriz en lugar de comenzar.
Aquí hay un ejemplo:

irb> [2, 5, 1, nil, 7, 3, nil, nil, 4, 6].sort_by { |i| [i ? 1 : 0, i] } => [nil, nil, nil, 1, 2, 3, 4, 5, 6, 7] irb> [2, 5, 1, nil, 7, 3, nil, nil, 4, 6].sort_by { |i| [i ? 0 : 1, i] } => [1, 2, 3, 4, 5, 6, 7, nil, nil, nil]