String 根据unicode对字符串进行排序

String 根据unicode对字符串进行排序,string,unicode,elixir,string-comparison,String,Unicode,Elixir,String Comparison,我有一个列表,我想按字母顺序排序,但要考虑unicode iex(2)> ["lubelskie", "łódzkie", "mazowieckie", "zachodniopomorskie"] |> Enum.sort ["lubelskie", "mazowieckie", "zachodniopomorskie", "łódzkie"] # the above is wrong, it should be: ["lubelskie", "łódzkie", "mazowiec

我有一个列表,我想按字母顺序排序,但要考虑unicode

iex(2)> ["lubelskie", "łódzkie", "mazowieckie", "zachodniopomorskie"] |> Enum.sort
["lubelskie", "mazowieckie", "zachodniopomorskie", "łódzkie"]
# the above is wrong, it should be:
["lubelskie", "łódzkie", "mazowieckie", "zachodniopomorskie"]

我怎样才能在长生不老药中做到这一点?使用一些十六进制软件包是可以接受的。

到目前为止,由于使用的字母表定义良好,我最终创建了自己的排序功能:

  defp numeric_for_sort(string) do
    letters = ["a", "ą", "b", "c", "ć", "d", "e", "ę", "f", "g", "h", "i", "j", "k", "l", "ł",
               "m", "n", "ń", "o", "ó", "p", "q", "r", "s", "ś", "t", "u", "w", "y", "z", "ź", "ż"]
    String.graphemes(string)
    |> Enum.map(fn(x) -> Enum.find_index(letters, fn(y) -> x == y end) end)
  end
然后

Enum.sort(["lubelskie", "mazowieckie", "zachodniopomorskie", "łódzkie"], &(numeric_for_sort(&1["name"]) <= numeric_for_sort(&2["name"])))
Enum.sort([“lubelskie”、“mazowieckie”、“zachodniopomorskie”、“łódzkie”],&(数字_表示_排序(&1[“name”]))
远非十全十美,但确实有效

这对我不起作用:

my.exs:

defmodule Stuff do
  def numeric_for_sort(string) do
    letters = ["a", "ą", "b", "c", "ć", "d", "e", "ę", "f", "g", "h", "i", "j", "k", "l", "ł",
               "m", "n", "ń", "o", "ó", "p", "q", "r", "s", "ś", "t", "u", "w", "y", "z", "ź", "ż"]
    String.graphemes(string)
    |> Enum.map(fn(x) -> Enum.find_index(letters, fn(y) -> x == y end) end)
  end
end

然后:

根据文件:

sort_by/3与sort/2的不同之处在于,它只计算一次可枚举项中每个元素的比较值,而不是 每次比较中的每个元素一次。如果使用相同的函数 由于两个元素都被调用,所以它的使用也更加紧凑 按/3排序

排序时会进行许多比较,对于排序算法进行的每次比较,反复计算每个名称的数字列表显然不理想

请注意,即使这一行:

Enum.sort_by names, &Stuff.numeric_for_sort/1

看起来它调用的是sort_by/2,实际上它调用的是sort_by/3,默认的第三个参数是
&处理排序的正确方法是将所有字符带到并排序。问题是由于某种原因
“ł”
不被视为一个组合形式:

字母
|>Enum.map(&:unicode.characters_to_nfd_binary/1)
|>Enum.map(&String.codepoints/1)
#⇒ [
#[“a”],
#[“a”、“̨”],
#[“b”],
#[“c”],
#[“c”、“́”],
#[“d”],
#[“e”],
#[“e”、“̨”],
#[“f”],
#[“g”],
#[“h”],
#[“i”],
#[“j”],
#[“k”],
#[“l”],
#  ["ł"],
#[“m”],
#[“n”],
#[“n”、“́”],
#[“o”],
#[“o”、“́”],
#[“p”],
#[“q”],
#[“r”],
#[“s”],
#[“s”、“́”],
#[“t”],
#[“u”],
#[“w”],
#[“y”],
#[“z”],
#[“z”、“́”],
#[“z”、“̇”]
# ]

我不知道为什么<代码>(<)>代码>没有被声明为组合的字母,我也认为这是联盟文件中的一个bug。无论如何,我们可能会愚弄排序器:

[“卢贝尔斯基”、“奥德斯基”、“马佐维茨基”、“扎乔德尼奥莫斯基”]
|>Enum.map(&:unicode.characters_to_nfd_binary/1)
|>Enum.map(&String.replace)(&1,“ł”,“l�"))
|>Enum.sort()
|>Enum.map(&String.replace)(&1,“l�", "ł"))
#⇒ [“卢贝尔斯基”、“奥兹基”、“马佐维茨基”、“扎乔德尼奥莫斯基”]

现在它可以处理任何输入,包括合成的和分解的。

关于Unicode“到底意味着什么?是按代码单元(哪个字符集)来的吗,代码点,一些特定语言的映射,什么?它不起作用。你完全忽略组合变音符号。@mudasobwa我不确定你的意思是什么如果输入是组合变音符号,即o后跟重音,你的分类器将失败。但它起作用…可能在100%的情况下不起作用-这就是你的意思吗?组合变音符号共有8个字符,请将我的评论复制粘贴到另一个答案。这将复制粘贴
[“lubelskie”,“łódzkie”]
,并对此感到惊讶。人们无法避免使用组合变音符号。
letters = ["a", "ą", "b", "c", "ć", "d", "e", "ę", "f", "g", "h", "i", "j", "k", "l", "ł",
           "m", "n", "ń", "o", "ó", "p", "q", "r", "s", "ś", "t", "u", "w", "y", "z", "ź", "ż"]
letter_rank = Map.new Enum.with_index letters
String.graphemes(string)
|> Enum.map(fn(x) -> letter_rank[x] end)
names = ["lubelskie", "łódzkie", "mazowieckie", "zachodniopomorskie"] 
["lubelskie", "łódzkie", "mazowieckie", "zachodniopomorskie"]

iex(2)> Enum.sort_by names, &Stuff.numeric_for_sort/1
["lubelskie", "łódzkie", "mazowieckie", "zachodniopomorskie"]

iex(3)> 
Enum.sort_by names, &Stuff.numeric_for_sort/1