Ruby 自定义排序
Ruby Custom Sorting
我在 Ruby 中得到了以下数组。
arr = [
[13.0, ["mango", "banana", "jackfruit"]],
[10.0, ["mango", "Milk", "Cofee"]],
[4.0, ["mango"]]
[5.0, ["jackfruit"]],
[6.0, ["mango", "banana"]],
[5.0, ["mango", "banana"]],
[10.0, ["banana", "jackfruit"]],
[5.0, ["banana"]],
]
我希望结果按以下规则排序:
- 先按Fruit数组的长度排序(有些如何分组)
- 按低价-高价排序。
预期输出:
[
[10.0, ["mango", "Milk", "Cofee"]],
[13.0, ["mango", "banana", "jackfruit"]],
[5.0, ["mango", "banana"]],
[6.0, ["mango", "banana"]],
[10.0, ["banana", "jackfruit"]],
[4.0, ["mango"]]
[5.0, ["jackfruit"]],
[5.0, ["banana"]],
]
说明:首先根据水果数组的长度对元素进行分类,然后在每个集合上根据它们的价格(低-高)进行排序。
我尝试了以下代码,但没有给出预期的结果!
arr.group_by{|x| x[1].length }.sort_by{|x| x[0]}.map{|x| x[1]}
您不需要进行任何特殊分组。
arr.sort {|a, b| (b[1].length <=> a[1].length) * 10 + (a[0] <=> b[0]) }
结果:
[
[10.0, ["mango", "Milk", "Cofee"]],
[13.0, ["mango", "banana", "jackfruit"]],
[5.0, ["mango", "banana"]],
[6.0, ["mango", "banana"]],
[10.0, ["banana", "jackfruit"]],
[4.0, ["mango"]],
[5.0, ["jackfruit"]],
[5.0, ["banana"]]
]
#sort
通过产量值进行比较。 <=>
returns -1、0 或 1,具体取决于它们的比较方式,因此由于您想优先考虑长度而不是价格,因此每件商品的 "sort weight"(长度比较 * 10 ) + (价格比较).
这里不需要过于聪明的比较器,您按数字排序,因此简单的否定可以反转排序,sort_by
可以处理其余部分。例如:
arr.sort_by { |e| [-e.last.length, e.first] }
或者如果您更喜欢数字索引:
arr.sort_by { |e| [-e[1].length, e[0]] }
会给你:
[
[10.0, ["mango", "Milk", "Cofee"]],
[13.0, ["mango", "banana", "jackfruit"]],
[ 5.0, ["mango", "banana"]],
[ 6.0, ["mango", "banana"]],
[10.0, ["banana", "jackfruit"]],
[ 4.0, ["mango"]],
[ 5.0, ["jackfruit"]],
[ 5.0, ["banana"]]
]
随心所欲。 Array#<=>
逐个元素进行比较,因此 sort_by
使用生成数组的块非常常见。
尽管您可能想为比较添加更多条件,但您所拥有的并不能保证 [11.0, ['a', 'b', 'c']]
和 [11.0, ['x', 'y', 'z']]
的显示顺序。
我在 Ruby 中得到了以下数组。
arr = [
[13.0, ["mango", "banana", "jackfruit"]],
[10.0, ["mango", "Milk", "Cofee"]],
[4.0, ["mango"]]
[5.0, ["jackfruit"]],
[6.0, ["mango", "banana"]],
[5.0, ["mango", "banana"]],
[10.0, ["banana", "jackfruit"]],
[5.0, ["banana"]],
]
我希望结果按以下规则排序:
- 先按Fruit数组的长度排序(有些如何分组)
- 按低价-高价排序。
预期输出:
[
[10.0, ["mango", "Milk", "Cofee"]],
[13.0, ["mango", "banana", "jackfruit"]],
[5.0, ["mango", "banana"]],
[6.0, ["mango", "banana"]],
[10.0, ["banana", "jackfruit"]],
[4.0, ["mango"]]
[5.0, ["jackfruit"]],
[5.0, ["banana"]],
]
说明:首先根据水果数组的长度对元素进行分类,然后在每个集合上根据它们的价格(低-高)进行排序。
我尝试了以下代码,但没有给出预期的结果!
arr.group_by{|x| x[1].length }.sort_by{|x| x[0]}.map{|x| x[1]}
您不需要进行任何特殊分组。
arr.sort {|a, b| (b[1].length <=> a[1].length) * 10 + (a[0] <=> b[0]) }
结果:
[
[10.0, ["mango", "Milk", "Cofee"]],
[13.0, ["mango", "banana", "jackfruit"]],
[5.0, ["mango", "banana"]],
[6.0, ["mango", "banana"]],
[10.0, ["banana", "jackfruit"]],
[4.0, ["mango"]],
[5.0, ["jackfruit"]],
[5.0, ["banana"]]
]
#sort
通过产量值进行比较。 <=>
returns -1、0 或 1,具体取决于它们的比较方式,因此由于您想优先考虑长度而不是价格,因此每件商品的 "sort weight"(长度比较 * 10 ) + (价格比较).
这里不需要过于聪明的比较器,您按数字排序,因此简单的否定可以反转排序,sort_by
可以处理其余部分。例如:
arr.sort_by { |e| [-e.last.length, e.first] }
或者如果您更喜欢数字索引:
arr.sort_by { |e| [-e[1].length, e[0]] }
会给你:
[
[10.0, ["mango", "Milk", "Cofee"]],
[13.0, ["mango", "banana", "jackfruit"]],
[ 5.0, ["mango", "banana"]],
[ 6.0, ["mango", "banana"]],
[10.0, ["banana", "jackfruit"]],
[ 4.0, ["mango"]],
[ 5.0, ["jackfruit"]],
[ 5.0, ["banana"]]
]
随心所欲。 Array#<=>
逐个元素进行比较,因此 sort_by
使用生成数组的块非常常见。
尽管您可能想为比较添加更多条件,但您所拥有的并不能保证 [11.0, ['a', 'b', 'c']]
和 [11.0, ['x', 'y', 'z']]
的显示顺序。