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]