0
array = [{ name:'Joe', foo:'bar' },
         { name:'Bob', foo:''    },
         { name:'Hal', foo:'baz' }
        ]

什么是一种雄辩的排序方式,以便如果 foo 为空,则将其放在末尾,而不改变其他元素的顺序?

红宝石 1.9.3

4

5 回答 5

5
array.partition { |h| !h[:foo].empty? }.flatten
于 2013-02-12T23:35:12.383 回答
1

可以将键生成为元组,其中第一部分表示 null/not-null,第二部分是原始索引,然后是 sort_by [nulls_last, original_index]。

def sort_nulls_last_preserving_original_order array 
  array.map.with_index.
    sort_by { |h,i| [ (h[:foo].empty? ? 1 : 0), i ] }.
    map(&:first)
end

请注意,这避免了其他一些答案的所有粗略数组突变,并且是由纯函数转换构造的。

于 2013-02-13T06:09:02.220 回答
1
array = [
  { name:'Joe', foo:'bar' },
  { name:'Bob', foo:''    },
  { name:'Hal', foo:'baz' }
]

arraydup = array.dup
array.delete_if{ |h| h[:foo].empty? }
array += (arraydup - array)

结果是:

[
    [0] {
        :name => "Joe",
        :foo => "bar"
    },
    [1] {
        :name => "Hal",
        :foo => "baz"
    },
    [2] {
        :name => "Bob",
        :foo => ""
    }
]

通过一点重构:

array += ((array.dup) - array.delete_if{ |h| h[:foo].empty? })
于 2013-02-12T23:28:10.223 回答
1
array.find_all{|elem| !elem[:foo].empty?} + array.find_all{|elem| elem[:foo].empty?}

返回

[{:name=>"Joe", :foo=>"bar"}, {:name=>"Hal", :foo=>"baz"}, {:name=>"Bob", :foo=>""}]
于 2013-02-12T23:29:58.393 回答
0
array.each_with_index do |item, index|
  array << (array.delete_at(index)) if item[:foo].blank?
end

使用任何你有的东西来代替blank?.

于 2013-02-12T23:28:59.907 回答