如何根据非标准字母表对字符串数组进行排序?
How can I sort an array of strings based on a non standard alphabet?
我正在尝试按字母顺序对一组世界语短语进行排序。有没有办法使用 sort_by
来完成这个?
我正在根据世界语字母表中的索引检查字符串的每个字符,每个增加的索引在排序优先级中都会降低一步:
esp_alph = " abcĉdefgĝhĥijĵklmnoprsŝtuŭvz"
arr.sort_by {|string|
[esp_alph.index(string[0]),
esp_alph.index(string[1]),
esp_alph.index(string[2]),
esp_alph.index(string[3])]}
但是,这不是一个可扩展的解决方案,如果我的条件多于字符串中的字符,它就会中断。根据我的字符串长度,我似乎正处于循环的风口浪尖,但我无法弄清楚如何在没有语法错误的情况下实现它。还是有更好的方法来解决这个问题?
esp_alph = " abcĉĉdefgĝĝhĥĥijĵĵklmnoprsŝŝtuŭŭvz"
arr = ["abc\u0302a", "abĉa","abca" ]
p arr.sort_by {|string| string.chars.map{|c| esp_alph.index(c)}}
# => ["abca", "abĉa", "abĉa"]
为了更好的性能,esp_alph
字符串可能应该是哈希。
只需将世界语字母表中的所有字符替换为 ASCII 中的一些字符 table,以便世界语字母顺序与 ASCII 顺序匹配。
假设世界语字母表按照您给出的顺序排列,我假设它们的顺序是这样的:
esp_alph = " abcĉdefgĝhĥijĵklmnoprsŝtuŭvz"
并取出相同长度的ASCII字符table的任意部分(注意\
是单个字符):
ascii = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\"
或
ascii = "@-\"
然后,你可以简单地做:
arr.sort_by{|string| string.tr(esp_alph, ascii)}
在这里,tr
比 gsub
快,而且我认为它足够扩展。
ESP_ALPH = "abcĉdefgĝhĥijĵklmnoprsŝtuŭvz"
ESP_MAP = ESP_ALPH.each_char.with_index.to_a.to_h
#=> {"a"=> 0, "b"=> 1, "c"=> 2, "ĉ"=> 3, "d"=> 4, "e"=> 5, "f"=> 6,
# "g"=> 7, "ĝ"=> 8, "h"=> 9, "ĥ"=>10, "i"=>11, "j"=>12, "ĵ"=>13,
# "k"=>14, "l"=>15, "m"=>16, "n"=>17, "o"=>18, "p"=>19, "r"=>20,
# "s"=>21, "ŝ"=>22, "t"=>23, "u"=>24, "ŭ"=>25, "v"=>26, "z"=>27}
def sort_esp(str)
str.each_char.sort_by { |c| ESP_MAP[c] }.join
end
str = ESP_ALPH.chars.shuffle.join
#=> "hlbzŭvŝerĝoipjafntĵsmgĉdukĥc"
sort_esp(str) == ESP_ALPH
#=> true
我正在尝试按字母顺序对一组世界语短语进行排序。有没有办法使用 sort_by
来完成这个?
我正在根据世界语字母表中的索引检查字符串的每个字符,每个增加的索引在排序优先级中都会降低一步:
esp_alph = " abcĉdefgĝhĥijĵklmnoprsŝtuŭvz"
arr.sort_by {|string|
[esp_alph.index(string[0]),
esp_alph.index(string[1]),
esp_alph.index(string[2]),
esp_alph.index(string[3])]}
但是,这不是一个可扩展的解决方案,如果我的条件多于字符串中的字符,它就会中断。根据我的字符串长度,我似乎正处于循环的风口浪尖,但我无法弄清楚如何在没有语法错误的情况下实现它。还是有更好的方法来解决这个问题?
esp_alph = " abcĉĉdefgĝĝhĥĥijĵĵklmnoprsŝŝtuŭŭvz"
arr = ["abc\u0302a", "abĉa","abca" ]
p arr.sort_by {|string| string.chars.map{|c| esp_alph.index(c)}}
# => ["abca", "abĉa", "abĉa"]
为了更好的性能,esp_alph
字符串可能应该是哈希。
只需将世界语字母表中的所有字符替换为 ASCII 中的一些字符 table,以便世界语字母顺序与 ASCII 顺序匹配。
假设世界语字母表按照您给出的顺序排列,我假设它们的顺序是这样的:
esp_alph = " abcĉdefgĝhĥijĵklmnoprsŝtuŭvz"
并取出相同长度的ASCII字符table的任意部分(注意\
是单个字符):
ascii = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\"
或
ascii = "@-\"
然后,你可以简单地做:
arr.sort_by{|string| string.tr(esp_alph, ascii)}
在这里,tr
比 gsub
快,而且我认为它足够扩展。
ESP_ALPH = "abcĉdefgĝhĥijĵklmnoprsŝtuŭvz"
ESP_MAP = ESP_ALPH.each_char.with_index.to_a.to_h
#=> {"a"=> 0, "b"=> 1, "c"=> 2, "ĉ"=> 3, "d"=> 4, "e"=> 5, "f"=> 6,
# "g"=> 7, "ĝ"=> 8, "h"=> 9, "ĥ"=>10, "i"=>11, "j"=>12, "ĵ"=>13,
# "k"=>14, "l"=>15, "m"=>16, "n"=>17, "o"=>18, "p"=>19, "r"=>20,
# "s"=>21, "ŝ"=>22, "t"=>23, "u"=>24, "ŭ"=>25, "v"=>26, "z"=>27}
def sort_esp(str)
str.each_char.sort_by { |c| ESP_MAP[c] }.join
end
str = ESP_ALPH.chars.shuffle.join
#=> "hlbzŭvŝerĝoipjafntĵsmgĉdukĥc"
sort_esp(str) == ESP_ALPH
#=> true