2012-11-05 32 views
3

我有一个字符串数组,我希望按字母顺序排列,但顶部有一些默认值。例如:按字母顺序排列的顶部有多个默认值

["a", "b", "default1", "d", "default2", "c", "e"] 

,我想结果是:

["default1", "default2", "a", "b", "c", "d", "e"] 

某人有一个想法,我怎么能做到这一点容易吗?

UPDATE

的默认值也包括在阵列中,阵列是按字母顺序排列。

+1

都是默认的东西你加明确,或者是他们包括数组中,并希望迫使他们到最佳? –

+0

是预先订购的输入数组?如果没有,是按字母顺序排列的默认值? – tokland

回答

6

可枚举包括partition

data = ["a", "b", "default1", "d", "default2", "c", "e"] 
data.partition{ |d| d['default'] }.flatten 
=> ["default1", "default2", "a", "b", "d", "c", "e"] 

如果你得到的数据是没有排序成你想要的最后命令,你可以预先排序前划分它:

data = ["c", "b", "default2", "a", "default1", "e", "d"] 
data.sort.partition{ |d| d['default'] }.flatten 
=> ["default1", "default2", "a", "b", "c", "d", "e"] 

如果你需要一个更智能和全面的排序算法要处理各种“默认”条目,您可能可以使用sortsort_by,并使用lambda或proc来指示默认值和常规条目之间的差异,并返回所需的-101值。

+0

好的答案,你可以测试几乎任何东西来构建分区,易于阅读! –

+0

使用'partition'是一个不错的解决方案,唯一的问题是如果在第二种情况下,所需的默认值不是按字母顺序排列的(问题没有详细说明)。一个非常小的挑剔:我会写'flatten(1)'来表明我想要一个级别扁平化以拆分分区(恕我直言,不幸的是'flatten'是默认递归的) – tokland

+0

OP的问题没有指定很多重要的事情,我同意扁平化不应该是递归的。这个问题,'partition'的结果是数组的有限深度数组,'flatten'没有参数是安全的。 –

4

事情是这样工作的:

array = ["a", "b", "default1", "d", "default2", "c", "e"] 
defaults = ["default1", "default2"] #Add more if needed 
sorted_array = array.sort{|a, b| defaults.include?(a) ? -1 : defaults.include?(b) ? 1 : a <=> b } 
puts sorted_array # => ["default1", "default2", "a", "b" "c", "d", "e"] 
+0

非常感谢!我认为瘦人的解决方案稍微干净一点,但这也是一个非常好的解决方案。只能接受一个:(要详细说明我的问题 –

3

以通过数组定义字典顺序的优点,我会写:

defaults = Hash[["default1", "default2"].to_enum.with_index.to_a] 
xs = ["a", "b", "default1", "d", "default2", "c", "e"] 
xs.sort_by { |x| [defaults[x] || defaults.size, x] } 
#=> ["default1", "default2", "a", "b", "c", "d", "e"]