I have an array of objects that I need to sort by a position attribute that could be an integer or nil, and I need the objects that have the nil position to be at the end of the array. Now, I can force the position to return some value rather than nil so that the array.sort doesn't fail, but if I use 0 as this default, then it puts those objects at the front of the sort. What's the best way to to do this sort? should I just set the nil values to some ridiculously high number that is 'almost' always guaranteed to be at the end? or is there some other way i could cause the array.sort method to put the nil attribute objects at the end of the array? the code looks like this:
class Parent def sorted_children children.sort{|a, b| a.position <=> b.position} end end class Child def position category ? category.position : #what should the else be?? end end
now, if i make the 'else' something like 1000000000, then it's most likely gonna put them at the end of the array, but I don't like this solution as it's arbitrary
You can use the sort method on an array, hash, or another Enumerable object & you'll get the default sorting behavior (sort based on <=> operator) You can use sort with a block, and two block arguments, to define how one object is different than another (block should return 1, 0, or -1)
nil? will only return true if the object itself is nil. That means that an empty string is NOT nil and an empty array is NOT nil. Neither is something that is false nil. => NilClassnil.
When you want to remove nil elements from a Ruby array, you can use two methods: compact or compact! . They both remove nil elements, but compact! removes them permanently. In this shot, we will be talking about the compact!
The Array#sort method in Ruby uses the venerable Quicksort algorithm. In its best case, Quicksort has time complexity O(n log n), but in cases where the data to be sorted is already ordered, the complexity can grow to O(n2).
I would just tweak your sort to put nil
items last. Try something like this.
foo = [nil, -3, 100, 4, 6, nil, 4, nil, 23] foo.sort { |a,b| a && b ? a <=> b : a ? -1 : 1 } => [-3, 4, 4, 6, 23, 100, nil, nil, nil]
That says: if a and b are both non-nil sort them normally but if one of them is nil, return a status that sorts that one larger.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With