# BOO大全/阵列与串列

### 阵列与串列

```# an array literal!
>>> intarr = (1,20,40,2)
(1, 20, 40, 2)
>>> intarr.Length
4
>>> len(intarr) # Python style
4
# indexing
>>> intarr[1]
20
# can modify arrays
>>> intarr[1] = 40
40
>>> intarr
(1, 40, 40, 2)
# can slice arrays
>>> intarr[1:3]
(40, 40)
```

```arr = new int[]{1,20,40,2};
```

```>>> (1,10,2.3)
(1, 10, 2.3)
```

```>>>('one','two','three')
('one', 'two', 'three')
>>>aa = ((1,2),(3,4))
((1, 2), (3, 4))
>>>aa[0][1]
2
>>>print aa.GetType()
System.Int32[][]
>>>print aa[0].GetType()
System.Int32[]
```

```>>>bb=(1,'one',(1,2))
(1, 'one', (1, 2))
>>>print bb.GetType()
System.Object[]
```

```>>>dd=(of double:1,2,3,4,5)
(1, 2, 3, 4, 5)
>>>print dd.GetType()
System.Double[]
```

```>>>nums = array(double,20)
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
>>>print nums.GetType()
System.Double[]
```

#### 拆封值

```>>>x = 1.0
>>>y = 2.0
>>>res = x,y
(1, 2)
>>>print res.GetType()
System.Double[]
```

Boo 支援变数拆封。指派的左边可以使用多个变数，如果运算式有顺序的话，变数将会被顺序指定。

```>>>a,b = res
>>>print a,b
1 2
>>>y,x = x,y
>>>print x,y
2 1
```

```>>> a,b = x
----------^
ERROR: Cannot iterate over expression of type 'System.Double'.
```

#### 迭代

```arr = (1,3,20,4,5)

for i in range(0, arr.Length):
print arr[i]
```

```for i in arr:
print i
```

```list = [1,3,20,4,5]

for i as int in list:
print 2*i
```

for 回圈里，我们可以直接使用阵列﹔如果你只是要作一些简单的处理的话，这很方便：

```for i in (1,3,20,4,5):
print 2*i
```

#### 内建函数

Boo 提供了一些处理 enumerable 物件的内建函数。

##### join

```>>>a = (10,20,30)
>>>join(a,',')
'10,20,30'
>>>join(x for x in range(0,10))
'0 1 2 3 4 5 6 7 8 9'
```
##### zip

zip 用来把两个序列萃取为一个单一序列﹔新的序列里，每个元素将会包含它们对应的元素，而新的序列长度将会与两者最短的一样。如果你不明白的话，看看代码，代码远比解释来的清楚：

```>>>a = (10,20,30)
>>>b = (1,2,3)
>>>for i,j in zip(a,b): print i,j
10 1
20 2
30 3
>>>ls = [pair for pair in zip(a,b)]
>>>ls
[(10, 1), (20, 2), (30, 3)]
```
##### cat

cat 将会将两个序列串起来：

```>>>join(cat(a,b))
'10 20 30 1 2 3'
```
##### enumerate

enumerate传回的结果与zip非常相似，但第一个值却是索引值。

```>>>for i,s in enumerate(['one','two','three']): print i,s
0 one
1 two
2 three
>>>for i,line in enumerate(inf):
... 	print i,line
...
1 // Copyright (c) 2003, 2004, Rodrigo B. de Oliveira (rbo@acm.org)
3 //
```
##### iterator

iterator实际上并不太会被用到，但实际上你已经隐性地使用了(译注：这一节提到的内建函数，多数都有使用 iterator。)。它被用来为物件寻找一个适当的迭代子。在 Boo 里，输入流可以使用 for 来迭代印出，所以要印出档案里的内容，可以这么写：

```for line in inf: print line
```

```lines = array(string,iterator(inf))
```
##### reversed

```>>> ls = [1,2,3,4]
>>> l2 = [n for n in reversed(ls)]
[4, 3, 2, 1]
```

#### 串列

```>>> list = [2,4,5,2]
[2, 4, 5, 2]
[2, 4, 5, 2, 10]
>>> list.RemoveAt(3)
[2, 4, 5, 10]
>>> list.Remove(2)
[4, 5, 10]
>>> list.Insert(2,20)
[4, 5, 20, 10]
```

RemoveAtRemove 很容易造成误解﹔前者的引数是一个索引值，而后者的引数则是一个值。这一定要搞清楚，因为使用了错的方法不会有错误发生。

```>>> list.Contains(20)
true
>>> 20 in list
true
>>> list.IndexOf(20)
2
```

```>>> list = list + [30,40]
(List) [4, 5, 20, 10, 30, 40, 30, 40]
>>> list += [30,40]
(List) [4, 5, 20, 10, 30, 40]
>>> list.Extend([50,60])
(List) [4, 5, 20, 10, 30, 40, 30, 40, 50,60]
```

```>>> len(list)
9
>>> list.Length
---------^
ERROR: 'Length' is not a member of 'Boo.Lang.List'.
>>> list.Count
9
```

```>>>a = array(int,list)
(4, 5, 20, 10, 30, 40, 30, 40, 50)
>>>array(string,['one','two','three'])
('one', 'two', 'three')
>>> list = [2,4]
[2, 4]
>>>array(string,list)
System.InvalidCastException: At least one element in the source array
could not be cast down to the destination array type.
>>>array(string,x.ToString() for x in list)
('2', '4')
```

#### Generator运算式

```ii = []
for i in range(0, 10):

li = [i for i in range(0, 10)]
```

```>>>list = [2,4]
[2, 4]
>>>ls = [x.ToString() for x in list]
['2', '4']
>>>li = [i for i in range(0,10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>li = [2*i for i in range(0,10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>>li = [i for i in range(0,10) if i % 2 == 0]
[0, 2, 4, 6, 8]
```

Generator运算式实际上会产生一个可以迭代的物件(enumerator)。array内建函数可以使用这样的物件，所以程式也可以写成这样。要注意，你不必在Generator运算式的前后加上中括号。

```>>>ls=["alice","june","peter"]
['alice', 'june', 'peter']
>>>array(string,n.ToUpper() for n in ls)
('ALICE', 'JUNE', 'PETER')
```

#### Generator方法

```x = 0.0
while x < 5.0:
print x
x += 0.1
```

```def frange(x1 as double, x2 as double, xd as double):
x = x1
while x < x2:
yield x
x += xd

for x in frange(0,5.0,0.1):
print x
```