根据排序列表和升序打印数组值
Print array values based in sorting list and ascending order
请您帮忙。我有数组 "values",我想按 2 个条件排序。
第一个条件:使用数组"sortlist"中定义的排序列表。
第二个条件:从小到大。
使用我当前的脚本,我能够以正确的顺序打印第一个条件(排序列表)的值,但我不知道如何应用第二个排序条件(从最小到最大)。
ruby -e'
values = [ "Ghu_1","Prw_1","Prw_3","Prw_5","Vep_3","Hom_2","Vep_1","Hom_1","Prw_2","Vep_2","Prw_4" ]
sortlist = [ "Hom","Vep","Ghu","Prw" ]
sortlist.each{ |s|
values.each{ |v|
puts v if v.include?(s)
}
}'
Current Ouput # Desired output
Hom_2 # Hom_1
Hom_1 # Hom_2
Vep_3 # Vep_1
Vep_1 # Vep_2
Vep_2 # Vep_3
Ghu_1 # Ghu_1
Prw_1 # Prw_1
Prw_3 # Prw_2
Prw_5 # Prw_3
Prw_2 # Prw_4
Prw_4 # Prw_5
更新
谢谢塞巴斯蒂安。出色的。
它几乎可以工作,因为我注意到如果“_”之后的字符不是数字,则第二种排序是不正确的。例如,下面的输出对于 Pwr_XXX
的值不正确
ruby -e'
values = [ "Ghu_Klca","Prw_Rkdg","Prw_Ceteu","Prw_Eriir","Vep_Msas23","Hom_Ttgr5","Vep_Qsccas","Hom_Ftjh","Prw_jpolq","Vep_Szbqh","Prw_Lmnajh" ]
sortlist = [ "Hom","Vep","Ghu","Prw" ]
puts sortlist.flat_map{ |s|
values.select{ |v|
v if v.include?(s)
}.sort
}'
第二次更新
我的意思是第一种排序是基于sortlist数组。第二种排序是基于“_”之后的字符升序排列。在这种情况下,Prw 值的第一个字母是
C、E、j、L和R。但是当前输出是C、E、L、R和j。所以,j在最后,应该在L之后。我希望有道理。
Current output Expected output
Hom_Ftjh # Hom_Ftjh
Hom_Ttgr5 # Hom_Ttgr5
Vep_Msas23 # Vep_Msas23
Vep_Qsccas # Vep_Qsccas
Vep_Szbqh # Vep_Szbqh
Ghu_Klca # Ghu_Klca
Prw_Ceteu # Prw_Ceteu
Prw_Eriir # Prw_Eriir
Prw_Lmnajh # Prw_jpolq
Prw_Rkdg # Prw_Lmnajh
Prw_jpolq # Prw_Rkdg
看看你的代码,你可以做的是创建一个空数组,然后在你的 values.each
迭代中,将每个元素推送到你的空数组,如果该元素包含 sortlist
new_list = []
sortlist.each{ |s|
values.each{ |v|
new_list << v if v.include?(s)
}
}
然后使用 group_by
按第一个字符对它们进行分组:
p new_list.group_by{|e| e[0]}
# => {"H"=>["Hom_2", "Hom_1"], "V"=>["Vep_3", "Vep_1", "Vep_2"], "G"=>["Ghu_1"], "P"=>["Prw_1", "Prw_3", "Prw_5", "Prw_2", "Prw_4"]}
然后使用 flat_map
得到一个包含所有值的 "plain" 数组,但在迭代中为散列中的每个键对每个值进行排序:
p new_list.group_by{|e| e[0]}.flat_map{|_,v| v.sort}
# => ["Hom_1", "Hom_2", "Vep_1", "Vep_2", "Vep_3", "Ghu_1", "Prw_1", "Prw_2", "Prw_3", "Prw_4", "Prw_5"]
或 flat_map
、select
和 sort_by
组合(第二次更新):
values = [ "Ghu_Klca","Prw_Rkdg","Prw_Ceteu","Prw_Eriir","Vep_Msas23","Hom_Ttgr5","Vep_Qsccas","Hom_Ftjh","Prw_jpolq","Vep_Szbqh","Prw_Lmnajh" ]
sortlist = [ "Hom","Vep","Ghu","Prw" ]
p sortlist.flat_map{ |s|
values.select{ |v|
v if v.include?(s)
}.sort_by(&:downcase)
}
# => ["Hom_Ftjh", "Hom_Ttgr5", "Vep_Msas23", "Vep_Qsccas", "Vep_Szbqh", "Ghu_Klca", "Prw_Ceteu", "Prw_Eriir", "Prw_jpolq", "Prw_Lmnajh", "Prw_Rkdg"]
排序时使用sort_by(&:downcase)
到"ignore"大小写。
values.sort_by { |val|
front, back = val.split('_')
[sortlist.index(front), back.downcase]
}
# => ["Hom_1", "Hom_2", "Vep_1", "Vep_2", "Vep_3", "Ghu_1", "Prw_1", "Prw_2", "Prw_3", "Prw_4", "Prw_5"]
# or
# => ["Hom_Ftjh", "Hom_Ttgr5", "Vep_Msas23", "Vep_Qsccas", "Vep_Szbqh", "Ghu_Klca", "Prw_Ceteu", "Prw_Eriir", "Prw_Lmnajh", "Prw_Rkdg", "Prw_jpolq"]
这是有效的,因为数组通过比较第一个元素进行比较,如果前一个元素相等,则比较下一个元素。目前我正在比较 back
就好像它是一个字符串(10
在 2
之前);如果您想要数字排序(2
在 10
之前),请使用 back.to_i
或 back.to_f
(但这不适用于第二个示例)。
请您帮忙。我有数组 "values",我想按 2 个条件排序。
第一个条件:使用数组"sortlist"中定义的排序列表。 第二个条件:从小到大。
使用我当前的脚本,我能够以正确的顺序打印第一个条件(排序列表)的值,但我不知道如何应用第二个排序条件(从最小到最大)。
ruby -e'
values = [ "Ghu_1","Prw_1","Prw_3","Prw_5","Vep_3","Hom_2","Vep_1","Hom_1","Prw_2","Vep_2","Prw_4" ]
sortlist = [ "Hom","Vep","Ghu","Prw" ]
sortlist.each{ |s|
values.each{ |v|
puts v if v.include?(s)
}
}'
Current Ouput # Desired output
Hom_2 # Hom_1
Hom_1 # Hom_2
Vep_3 # Vep_1
Vep_1 # Vep_2
Vep_2 # Vep_3
Ghu_1 # Ghu_1
Prw_1 # Prw_1
Prw_3 # Prw_2
Prw_5 # Prw_3
Prw_2 # Prw_4
Prw_4 # Prw_5
更新
谢谢塞巴斯蒂安。出色的。
它几乎可以工作,因为我注意到如果“_”之后的字符不是数字,则第二种排序是不正确的。例如,下面的输出对于 Pwr_XXX
的值不正确 ruby -e'
values = [ "Ghu_Klca","Prw_Rkdg","Prw_Ceteu","Prw_Eriir","Vep_Msas23","Hom_Ttgr5","Vep_Qsccas","Hom_Ftjh","Prw_jpolq","Vep_Szbqh","Prw_Lmnajh" ]
sortlist = [ "Hom","Vep","Ghu","Prw" ]
puts sortlist.flat_map{ |s|
values.select{ |v|
v if v.include?(s)
}.sort
}'
第二次更新
我的意思是第一种排序是基于sortlist数组。第二种排序是基于“_”之后的字符升序排列。在这种情况下,Prw 值的第一个字母是 C、E、j、L和R。但是当前输出是C、E、L、R和j。所以,j在最后,应该在L之后。我希望有道理。
Current output Expected output
Hom_Ftjh # Hom_Ftjh
Hom_Ttgr5 # Hom_Ttgr5
Vep_Msas23 # Vep_Msas23
Vep_Qsccas # Vep_Qsccas
Vep_Szbqh # Vep_Szbqh
Ghu_Klca # Ghu_Klca
Prw_Ceteu # Prw_Ceteu
Prw_Eriir # Prw_Eriir
Prw_Lmnajh # Prw_jpolq
Prw_Rkdg # Prw_Lmnajh
Prw_jpolq # Prw_Rkdg
看看你的代码,你可以做的是创建一个空数组,然后在你的 values.each
迭代中,将每个元素推送到你的空数组,如果该元素包含 sortlist
new_list = []
sortlist.each{ |s|
values.each{ |v|
new_list << v if v.include?(s)
}
}
然后使用 group_by
按第一个字符对它们进行分组:
p new_list.group_by{|e| e[0]}
# => {"H"=>["Hom_2", "Hom_1"], "V"=>["Vep_3", "Vep_1", "Vep_2"], "G"=>["Ghu_1"], "P"=>["Prw_1", "Prw_3", "Prw_5", "Prw_2", "Prw_4"]}
然后使用 flat_map
得到一个包含所有值的 "plain" 数组,但在迭代中为散列中的每个键对每个值进行排序:
p new_list.group_by{|e| e[0]}.flat_map{|_,v| v.sort}
# => ["Hom_1", "Hom_2", "Vep_1", "Vep_2", "Vep_3", "Ghu_1", "Prw_1", "Prw_2", "Prw_3", "Prw_4", "Prw_5"]
或 flat_map
、select
和 sort_by
组合(第二次更新):
values = [ "Ghu_Klca","Prw_Rkdg","Prw_Ceteu","Prw_Eriir","Vep_Msas23","Hom_Ttgr5","Vep_Qsccas","Hom_Ftjh","Prw_jpolq","Vep_Szbqh","Prw_Lmnajh" ]
sortlist = [ "Hom","Vep","Ghu","Prw" ]
p sortlist.flat_map{ |s|
values.select{ |v|
v if v.include?(s)
}.sort_by(&:downcase)
}
# => ["Hom_Ftjh", "Hom_Ttgr5", "Vep_Msas23", "Vep_Qsccas", "Vep_Szbqh", "Ghu_Klca", "Prw_Ceteu", "Prw_Eriir", "Prw_jpolq", "Prw_Lmnajh", "Prw_Rkdg"]
排序时使用sort_by(&:downcase)
到"ignore"大小写。
values.sort_by { |val|
front, back = val.split('_')
[sortlist.index(front), back.downcase]
}
# => ["Hom_1", "Hom_2", "Vep_1", "Vep_2", "Vep_3", "Ghu_1", "Prw_1", "Prw_2", "Prw_3", "Prw_4", "Prw_5"]
# or
# => ["Hom_Ftjh", "Hom_Ttgr5", "Vep_Msas23", "Vep_Qsccas", "Vep_Szbqh", "Ghu_Klca", "Prw_Ceteu", "Prw_Eriir", "Prw_Lmnajh", "Prw_Rkdg", "Prw_jpolq"]
这是有效的,因为数组通过比较第一个元素进行比较,如果前一个元素相等,则比较下一个元素。目前我正在比较 back
就好像它是一个字符串(10
在 2
之前);如果您想要数字排序(2
在 10
之前),请使用 back.to_i
或 back.to_f
(但这不适用于第二个示例)。