排序字母数字数组?

时间:2013-12-26 23:45:37

标签: ruby

我想在Ruby中对一个字母数字数组进行排序,然后返回一个已排序的数组。

例如:

["world", "jim", 4, 1, "apple"]

返回:

["apple", "jim", 1, 4, "world"] 

所以在排序之前在相同位置存在同一个类的对象的地方,就在现在它是数字/字母。

5 个答案:

答案 0 :(得分:1)

xs            = ["world", "jim", 4, 1, "apple", 5, 6]
sorted_by_cls = xs.group_by(&:class).each { |k,vs| vs.sort!.reverse! }
sorted_xs     = xs.map(&:class).map { |c| sorted_by_cls[c].pop }

答案 1 :(得分:1)

不知道这与其他解决方案相比如何,但这是另一个解决方案:

xs = ["world", "jim", 4, 1, "apple", 5, 6]
classes = xs.map(&:class)
sorts = Hash[*classes.uniq.map {|c| [c, xs.select {|x| x.class == c}.sort]}.flatten(1)]
classes.map {|c| sorts[c].shift} # => ["apple", "jim", 1, 4, "world", 5, 6]

答案 2 :(得分:0)

arr = ["world", "jim", 4, 1, "apple"]

arr.each_with_index.group_by {|e| e.first.class}.values.map {|g|\
g.map(&:first).sort.zip(g.map(&:last).sort)}\
.each_with_object(Array.new(arr.size)) {|e,a| e.each {|f,i| a[i] = f}}
  # => ["apple", "jim", 1, 4, "world"]

让我们来看看:

  • a1 = arr.each.with_index.group_by {|e| e.first.class} # => {String=>[["world", 0], ["jim", 1], ["apple", 4]], Fixnum=>[[4, 2], [1, 3]]}
  • a21, a22 = a1.values #=>[[["world",0],["jim",1],["apple",4]],[[4,2],[1,3]]]
  • a31 = a21.map(&:first) # => ["world", "jim", "apple"]
  • a41 = a31.sort # => ["apple", "jim", "world"]
  • a51 = a21.map(&:last).sort # => [0, 1, 4]
  • a61 = a41.zip(a51) # => [["apple", 0], ["jim", 1], ["world", 4]]
  • a62 = a22.map(&:first).sort.zip(a22.map(&:last).sort) # => [[1,2], [4,3]]
  • [a61, a62].each_with_object(Array.new(5)) {|e,a| e.each {|f,i| a[i] = f}}

答案 3 :(得分:0)

一个非常有趣的问题。这是我假设一个字母数字数组接近它的方式。将数组划分为alpha和数字子数组,对它们进行排序,然后根据原始数组中对象的位置和类重新构建。

arr = ["world", "jim", 4, 1, "apple"]
alpha_num = arr.partition { |l| l.is_a? String }.map(&:sort)
arr.map { |l| l.is_a?(String) ? alpha_num.first.shift : alpha_num.last.shift }

我的广义解决方案与FMc没有太大区别:

arr = ["world", "jim", 4, 1, "apple", 5, 6]
sorted_hash = arr.group_by(&:class).each_value(&:sort!)
arr.map { |l| sorted_hash[l.class].shift }

答案 4 :(得分:0)

a = ["world", "jim", 4, 1, "apple", "cabbage"]

is = a.each_index.group_by{|i| a[i].class}.values
.flat_map{|is| [is, is.sort_by{|i| a[i]}].transpose}
.sort.map(&:last)
a.values_at(*is)