# 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
```