Skip to content

Commit

Permalink
[CN] update basics (elixirschool#1067)
Browse files Browse the repository at this point in the history
* [CN] update basics

* [CN] update basics/collections.md

* [CN] update basics/enum.md to 1.0.0
  • Loading branch information
Cifer-Y authored and cizixs committed May 9, 2017
1 parent 6233588 commit 412f6da
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 24 deletions.
71 changes: 65 additions & 6 deletions cn/lessons/basics/basics.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
version: 0.9.0
version: 1.0.0
layout: page
title: 基础
category: basics
Expand All @@ -15,18 +15,38 @@ lang: cn

### 安装 Elixir

各个 os 的安装说明可以在 Elixir-lang.org 网站上 [Installing Elixir](http:https://elixir-lang.org/install.html) 部分找到。
各个 os 的安装说明可以在 elixir-lang.org 网站上 [Installing Elixir](http:https://elixir-lang.org/install.html) 部分找到。

安装后你可以很轻松的确认所安装的版本。

% elixir -v
Erlang/OTP {{ site.erlang.OTP }} [erts-{{ site.erlang.erts }}] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Elixir {{ site.elixir.version }}

### 交互模式

Elixir 自带了 `iex` 这样一个交互 shell, 可以让我们随时计算 Elixir 表达式的值。

运行 `iex` 命令,让我们开始教程:

Erlang/OTP {{ site.erlang.OTP }} [erts-{{ site.erlang.erts }}] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Erlang/OTP {{ site.erlang.OTP }} [erts-{{ site.erlang.erts }}] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir ({{ site.elixir.version }}) - press Ctrl+C to exit (type h() ENTER for help)
iex>

让我们继续输入几个简单的表达式试试:

```elixir
iex> 2+3
5
iex> 2+3 == 5
true
iex> String.length("The quick brown fox jumps over the lazy dog")
43
```

Interactive Elixir ({{ site.elixir.version }}) - press Ctrl+C to exit (type h() ENTER for help)
iex>
如果你现在还无法理解所有的表达式,请不要担心,不过我们希望你能有所体会。

## 基本类型

Expand Down Expand Up @@ -130,6 +150,8 @@ iex> "foo\nbar"
"foo\nbar"
```

Elixir 还包含很多复杂的数据类型。当我们学到集合和函数的时候我们会学到更多关于这方面的知识。

## 基本操作

### 算术运算
Expand Down Expand Up @@ -177,7 +199,7 @@ iex> !false
true
```

还有三个操作符(`and``or``not`),它们的第一个参数必须是布尔类型`true``false`):
还有三个操作符(`and``or``not`),它们的第一个参数_必须_是布尔类型`true``false`):

```elixir
iex> true and 42
Expand All @@ -194,6 +216,43 @@ iex> not 42

### 比较

Elixir 有我们习惯的一切比较运算符 :`==`, `!=`, `===`, `!==`, `<=`, `>=`, `<``>`

```elixir
iex> 1 > 2
false
iex> 1 != 2
true
iex> 2 == 2
true
iex> 2 <= 3
true
```

对于整数和浮点数的严格比较,可以使用 `===`

```elixir
iex> 2 == 2.0
true
iex> 2 === 2.0
false
```

Elixir 有一个很重要的特性,那就是任意两个类型之间都可以进行比较,这在排序的时候非常有用。我们没有必要去记住比较的优先级,但是知道了也没坏处 :

```elixir
number < atom < reference < function < port < pid < tuple < map < list < bitstring
```

这个特性可以导致一些非常有趣但是完全合法,而且在其他语言中很难看到的比较 :

```elixir
iex> :hello > 999
true
iex> {:hello, :world} > [1, 2, 3]
false
```

### 字符串插值

如果你使用过 Ruby,那么 Elixir 的字符串插值看起来会很熟悉:
Expand Down
12 changes: 7 additions & 5 deletions cn/lessons/basics/collections.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
version: 0.9.0
version: 1.0.0
layout: page
title: 集合
category: basics
Expand Down Expand Up @@ -41,7 +41,7 @@ iex> [1, 2] ++ [3, 4, 1]
[1, 2, 3, 4, 1]
```

关于上面使用到的 `++/2` 格式的说明:在 Elixir 中(以及 Elixir 的基础语言 Erlang),函数和操作符的名字由两部分组成:名字和元数(arity)。元数是 Elixir 和 Erlang 代码非常核心的部分,它代表了给定函数接受的参数个数(比如这里的 2),元数和名字之间通过斜线分割。我们后面会讲到更多这方面的内容,知道这些已经能帮你理解它的含义了。
关于上面使用到的 `++/2` 格式的说明:在 Elixir 中(以及 Elixir 的基础语言 Erlang),函数和操作符的名字由两部分组成:名字(比如这里的 `++`)和元数(arity)。元数是 Elixir 和 Erlang 代码非常核心的部分,它代表了给定函数接受的参数个数(比如这里的 2),元数和名字之间通过斜线分割。我们后面会讲到更多这方面的内容,知道这些已经能帮你理解它的含义了。

### 列表减法

Expand All @@ -57,7 +57,7 @@ iex> ["foo", :bar, 42] -- [42, "bar"]
iex> [1,2,2,3,2,3] -- [1,2,3,2]
[2, 3]

注意:这里的比较 是否相同使用的是[严格比较(strict comparison)](https://github.com/doomspork/elixir-school/blob/9321df59a92a765bf64363badab6fddfdb4fe11e/lessons/basics/#comparison)
**注意:**这里比较是否相同使用的是[严格比较(strict comparison)](../basics/#comparison)


### 头/尾
Expand All @@ -72,7 +72,7 @@ iex> tl [3.14, :pie, "Apple"]
[:pie, "Apple"]
```

除了上面的提到的函数,你还可以使用 `|` 操作符,我们在后面的教程中还会看到这种用法。
除了上面的提到的函数,你还可以使用[模式匹配(pattern matching)](../pattern-matching/)`|` 操作符来把一个列表分成头尾两部分;我们在后面的教程中还会看到这种用法。

```elixir
iex> [h|t] = [3.14, :pie, "Apple"]
Expand Down Expand Up @@ -103,7 +103,7 @@ iex> File.read("path/to/unknown/file")

## 关键字列表

关键字列表(keywords)和图(maps)是 Elixir 中两个相关的集合:它们都实现了 `Dict` 模块。Elixir 的关键字列表是一种特殊的列表:列表里的内容是二元元组,并且二元组的第一个元素必须是原子。它和列表的行为完全一致。
关键字列表(keywords)和图(maps)是 Elixir 中两个相关的集合。Elixir 的关键字列表是一种特殊的列表:列表里的内容是二元元组,并且二元组的第一个元素必须是原子。它和列表的行为完全一致。

```elixir
iex> [foo: "bar", hello: "world"]
Expand Down Expand Up @@ -135,10 +135,12 @@ iex> map["hello"]

Elixir 1.2 版本中,也可以把变量作为图的键(key):

```elixir
iex> key = "hello"
"hello"
iex> %{key => "world"}
%{"hello" => "world"}
```

如果重复的键添加到图中,后面的值会覆盖之前的值:

Expand Down
73 changes: 60 additions & 13 deletions cn/lessons/basics/enum.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
version: 0.9.0
version: 1.0.0
layout: page
title: Enum 模块
category: basics
Expand All @@ -15,11 +15,33 @@ lang: cn

`Enum` 模块提供了超过一百个函数,和我们上节课提到的集合交互。

这篇课程只会讲其中的一部分,要想了解全部的函数,请访问官方的 [`Enum`](http:https://elixir-lang.org/docs/stable/elixir/Enum.html) 文档。
而要想了解懒枚举(lazy enumeration),访问 [`Stream`](http:https://elixir-lang.org/docs/stable/elixir/Stream.html) 模块。
这节课程我们只会覆盖一部分函数,不过我们随时都可以自己去了解。
让我们在 IEx 里做个小试验。

```elixir
iex
iex> Enum.__info__(:functions) |> Enum.each(fn({function, arity}) ->
...> IO.puts "#{function}/#{arity}"
...> end)
all?/1
all?/2
any?/1
any?/2
at/2
at/3
...
```

通过上面的命令,很明显能看到我们有很多函数,而且这些函数都是师出有名。
集合在函数式编程中处于核心地位,同时也是非常有用的部分。
通过利用它与Elixir的其他优势相结合,比如我们刚看到的,文档是一等公民,可以赋予开发人员非常强大的能力。

要想了解全部的函数,请访问官方的 [`Enum`](http:https://elixir-lang.org/docs/stable/elixir/Enum.html) 文档。而要想了解惰性枚举(lazy enumeration),访问 [`Stream`](http:https://elixir-lang.org/docs/stable/elixir/Stream.html) 模块。


### all?
使用 `all?` 的时候,我们要提供一个函数来作用到要操作的集合上。只有当函数在所有的元素上都返回 `true` 的时候,`all?` 才会返回 `true`,否则结果就是 `false`

使用 `all?` 以及大部分 `Enum` 函数的时候,我们要提供一个函数来作用到要操作的集合上。只有当函数在所有的元素上都返回 `true` 的时候,`all?` 才会返回 `true`,否则结果就是 `false`

```elixir
iex> Enum.all?(["foo", "bar", "hello"], fn(s) -> String.length(s) == 3 end)
Expand All @@ -29,6 +51,7 @@ true
```

### any?

和上面不同,只要有一个元素被函数调用返回 `true``any?` 就会返回 `true`

```elixir
Expand All @@ -49,8 +72,7 @@ iex> Enum.chunk([1, 2, 3, 4, 5, 6], 2)

### chunk_by

如果不按照数量分组(每组的元素数量相同),我们可以使用 `chunk_by` 方法。它接受一个枚举值和一个函数作为参数,
如果函数的返回值变了,就是从新从后开始分组:
如果不按照数量分组(每组的元素数量相同),我们可以使用 `chunk_by` 方法。它接受一个枚举值和一个函数作为参数,如果函数的返回值变了,就是从新从后开始分组:

```elixir
iex> Enum.chunk_by(["one", "two", "three", "four", "five"], fn(x) -> String.length(x) end)
Expand All @@ -59,6 +81,15 @@ iex> Enum.chunk_by(["one", "two", "three", "four", "five", "six"], fn(x) -> Stri
[["one", "two"], ["three"], ["four", "five"], ["six"]]
```

### map_every

有时候把集合分组并不能满足我们的需求。这时候 `map_every/3` 在修改集合中特定元素的时候会非常有用:

```elixir
iex> Enum.map_every([1, 2, 3, 4], 2, fn x -> x * 2 end)
[2, 2, 6, 4]
```

### each

有时候需要遍历某个集合进行操作,但是不想产生新的值(不把函数的遍历调用结果返回),这种情况下,可以使用 `each`
Expand All @@ -84,22 +115,36 @@ iex> Enum.map([0, 1, 2, 3], fn(x) -> x - 1 end)

### min

在集合中找到最小的值:
`min/1` 在集合中找到最小的值:

```elixir
iex> Enum.min([5, 3, 0, -1])
-1
```

`min/2` 也一样,但是它允许我们提供一个匿名函数指定计算最小值的方法:

```elixir
iex> Enum.min([], fn -> :foo end)
:foo
```

### max

返回集合中最大的值:
`max/1` 返回集合中最大的值:

```elixir
iex> Enum.max([5, 3, 0, -1])
5
```

`max/2` 也一样,而且像 `min/2` 一样,它允许我们提供一个匿名函数指定计算最大值的方法:

```elixir
Enum.max([], fn -> :bar end)
:bar
```

### reduce

使用 `reduce`,我们可以把集合不断计算,最终得到一个值。我们需要提供一个可选的累加值(在这个例子中是 `10`),如果没有累加值,集合中的第一个值会被使用。
Expand All @@ -125,7 +170,7 @@ iex> Enum.sort([:foo, "bar", Enum, -1, 4])
[-1, 4, Enum, :foo, "bar"]
```

另外一个可是让允许我们自己提供排序函数
另外 `sort` 允许我们自己提供排序函数:

```elixir
# with our function
Expand All @@ -137,11 +182,13 @@ iex> Enum.sort([%{:count => 4}, %{:count => 1}])
[%{count: 1}, %{count: 4}]
```

### uniq
### uniq_by

我们可以使用 `uniq` 删除集合中的重复元素:
我们可以使用 `uniq_by/2` 删除集合中的重复元素:

```elixir
iex> Enum.uniq([1, 2, 2, 3, 3, 3, 4, 4, 4, 4])
[1, 2, 3, 4]
iex> Enum.uniq_by([1, 2, 3, 2, 1, 1, 1, 1, 1], fn x -> x end)
[1, 2, 3]
```

这跟我们以前都熟悉的 `uniq/1` 函数一样,但是这个函数在 Elixir 1.4 中被弃用,不过你还是可以使用它(会收到一个警告信息)。

0 comments on commit 412f6da

Please sign in to comment.