Elixir-字符串

目錄

  • 字符串
  • 字符列表
  • 字素和字碼點(diǎn)
  • 字符串函數(shù)
    • length/1
    • replace/3
    • duplicate/2
    • split/2
  • 練習(xí)
    • 重組字符串

字符串

Elixir 字符串就是字節(jié)序列

iex> string = <<104,101,108,108,111>>
"hello"

使用 << >> 是告訴編譯器這個(gè)符號(hào)里面的內(nèi)容是字節(jié)。

字符列表

在 Elixir 內(nèi)部,字符串是字節(jié)序列表示的,而不是字符數(shù)組。Elixir 也有一個(gè)字符列表的類型:字符串是雙引號(hào)括起來(lái)的,而字符列表是單引號(hào)括起來(lái)的。

這兩者有什么區(qū)別呢?字符列表的每個(gè)值都是 ASCII 碼。我們來(lái)深入了解一下。

iex> char_list = 'hello'
'hello'

iex> [hd|tl] = char_list
'hello'

iex> {hd, tl}
{104, 'ello'}

iex> Enum.reduce(char_list, "", fn char, acc -> acc <> to_string(char) <> "," end)
"104,101,108,108,111,"

在使用Elixir編程的時(shí)候,通常會(huì)使用字符串,而不是字符列表。字符列表之所以存在,是因?yàn)橛行?Erlang 模塊要用到它。

字素和字碼點(diǎn)

字碼點(diǎn)就是一個(gè)或者多個(gè)字節(jié)標(biāo)識(shí)的 Unicode 字符(根據(jù) UTF-8編碼方式,每個(gè)字碼點(diǎn)或有長(zhǎng)度的不同)。ASCII 碼之外的字符一般都由多個(gè)字節(jié)表示,比如帶有波浪線或者聲調(diào)的拉丁字符 (á, ?, è) 一般都是兩個(gè)字節(jié)表示的。而亞洲語(yǔ)言的字符一般都是三個(gè)或者四個(gè)字節(jié)。字素是一個(gè)字符的表示,通常由多個(gè)字碼點(diǎn)組成。

String 模塊已經(jīng)提供了兩個(gè)方法來(lái)獲取這兩種方式的值:graphemes/1codepoints/1。我們來(lái)看一下:

iex> string = "\u0061\u0301"
"á"

iex> String.codepoints string
["a", "?"]

iex> String.graphemes string
["á"]

字符串函數(shù)

這個(gè)部分我們看一下 String 模塊最常用的一些函數(shù)。本課程只會(huì)介紹其中的一部分,如果要了解所有的函數(shù),請(qǐng)參考官方 String 文檔。

length/1

返回字符串中字素的數(shù)量

iex> String.length("Hello")
5

replace/3

返回一個(gè)新的字符串,它的值是把原來(lái)某些模式替換成新的字符串得到的。

iex> String.replace("Hello", "e", "a")
"Hallo"

duplicate/2

返回重復(fù)了n遍的字符串。

iex> String.duplicate("Oh my ", 3)
"Oh my Oh my Oh my "

split/2

返回把原來(lái)字符串按照某個(gè)模式分割后的字符串列表。

iex> String.split("Hello World", " ")
["Hello", "World"]

練習(xí)

重組字符串

A 和 B 如果能通過重組變得和對(duì)方一樣,就認(rèn)為兩者是重組字符串。比如:

  • A = super
  • B = perus
    如果我們重組 A 字符串中的元素就可以得到 B,反之亦然。

那么,怎么才能用 Elixir 判斷字符串是否為重組字符串呢?最簡(jiǎn)單的方法就是對(duì)兩個(gè)字符串的字符進(jìn)行排序,然后比較排序好的結(jié)果是否相等。

defmodule Anagram do
  def anagrams?(a, b) when is_binary(a) and is_binary(b) do
    sort_string(a) == sort_string(b)
  end

  def sort_string(string) do
    string
    |> String.downcase()
    |> String.graphemes()
    |> Enum.sort()
  end
end

先看一下anagrams?/2,首先我們會(huì)檢查接受的參數(shù)是否為 binaries,這是 Elixir 檢查參數(shù)是否為字符串的方法。 然后,我們會(huì)調(diào)用把字符串按照字母表排序的函數(shù),這個(gè)函數(shù)首先把所有字符轉(zhuǎn)換成小寫,然后調(diào)用 String.graphemes 得到字符串中字素的列表。思路很清晰,對(duì)吧?

我們來(lái)通過 iex 看一下輸出結(jié)果:

iex> Anagram.anagrams?("Hello", "ohell")
true

iex> Anagram.anagrams?("María", "íMara")
true

iex> Anagram.anagrams?(3, 5)
** (FunctionClauseError) no function clause matching in Anagram.anagrams?/2

    The following arguments were given to Anagram.anagrams?/2:

        # 1
        3

        # 2
        5

    iex:11: Anagram.anagrams?/2

正如上面展示的,最后一次調(diào)用 anagrams?返回了 FunctionClauseError,這個(gè)錯(cuò)誤就是告訴我們模塊中沒有接受兩個(gè)非字符串的函數(shù)。這正是我們期望的結(jié)果:只接受字符串作為參數(shù),其他都不允許。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容