PJCHENder 未整理筆記

[Ruby] 陣列(Array)

2017-09-26

[Ruby] 陣列(Array)

@(Ruby on Rails)[Ruby]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## 陣列疊代
Array.each{|element|}
Array.collect{|element|}
Array.map{|element|}
Array.select{|element|} # 選出回傳為 true 的 element
Array.reject{|element|} # 刪掉回傳為 true 的 element
Array.each.with_index{|element, index|}
Array.all?{|element|} # 如果陣列裡面沒東西也會回傳 true
Array.any?{|element|}

## 陣列取用
Array.slice([start], [length])

## 添加元素
Array.push([element])
Array.insert([index], [element])
Array.unshift([element]) # 添加在最前面

## 其他
Array.flatten # 拆成一維陣列
Array.uniq # 移除陣列中相同的值
[*'A'..'Z'] # 產生 A...Z 的陣列
foo, bar = ['a', 'b'] # 陣列的解構賦值
1
2
3
# Rails 方法
Array.blank?
Array.present?

Array @ Ruby-doc

陣列建立

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
######################################
## 建立陣列 ##
######################################

# Array.new constructor
arr = Array.new() # []
arr = Array.new([repeat], [item])

# Array literal notation
arr = [ ] # []

# 建立帶值陣列
arr = Array.new(3,"Hello") # ["Hello","Hello","Hello"]
arr = [*1..52] # [1, 2, 3, ..., 51, 52]
arr = ["milk", "is", "good"] # ["milk","is","good"]
arr = %w(milk is good) # 如果陣列的元素都是字串,可以使用 %w ,回傳["milk", "is", "good"]
arr = %W(#{food} is good) # 大寫的 %W 可以 inteporated

# 建立帶有 symbol 的陣列
arr = %i(jan feb mar apr may jun jul aug sep oct nov dec) # [:jan, :feb, :mar, :apr, :may, :jun, :jul, :aug, :sep, :oct, :nov, :dec]

陣列取用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
######################################
## 陣列取用 ##
######################################

# 提取陣列元素(不會改變原本的 arr)
arr = ["milk", "bread", "egg"]
arr[0] # 根據索引值,["milk"]
arr[-1] # 根據索引值,["egg"]
arr[0..2] # 根據索引值,["milk", "bread", "egg"]
arr.at(1) # 根據索引值,["bread"]
arr.fetch(100, "what") # 根據索引值,如果無該元素,則以第二個參數為預設值,["what"]
arr.first # 提取第一個,["milk"]
arr.last # 提取最後一個,["egg"]
arr.drop(2) # 刪除前兩個陣列元素後再提取,["egg"]
arr.slice(1,2) # 從第 i 個元素開始取 j 個元素,["bread","egg"]

陣列操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
######################################
## 陣列操作 ##
######################################

# 為陣列添加元素(會改變原本的 arr)
arr = ["milk", "bread", "egg"]
arr << "apples" # 添加在最後面,["milk","bread","egg","apple"],concatenation operator
arr.push("orange") # 添加在最後面,["milk","bread","egg","orange"]
arr += ["ice-cream", "sugar"] # 添加在最後面,["milk", "bread", "egg", "ice-cream", "sugar"]
arr.unshfit(3) # 添加在最前面,[3, "milk", "bread", "egg"]
arr.insert(1,"carrot") # 插入指定位置,["milk", "carrot", "bread", "egg"]

# 為陣列刪除元素(會改變原本的 arr)
arr = ["milk", "bread", "egg"]
arr -= ["egg", "milk"] # 刪除指定元素,["bread"]
arr.pop # 刪除最後一個元素
arr.shift # 刪除第一個元素

# 其他方法
arr.length # 回傳陣列元素數目
arr.count # 回傳陣列元素數目
arr.count("milk") # 回傳陣列元素為 milk 的數目
arr.include?("apple") # 陣列是否包含該元素
arr.sort! # 根據陣列內容排序
arr.sort! { |a, b| a <=> b } # 如果要換排序方式可以改成 b <=> a

[*1..52].select { |i| i.odd? } # 選擇陣列中的元素
[*1..52].sample 5 # 從陣列中隨機抽取 5 個元素
[*1..52].shuffle # 將陣列元素順序打亂

輸出元素

1
2
3
arr.inspect
arr.to_s
arr.to_h # 陣列轉雜湊

Array.to_h: 陣列轉雜湊(array to hash)

1
[[:foo, :bar], [1, 2]].to_h    # => {:foo => :bar, 1 => 2}

陣列疊代

Array.collect{|i|}:疊代陣列

1
2
3
4
5
# 不會改變原陣列(immutable)
new_array = array.collect {|i| i * 2}

# 會改變原陣列(mutable)
array.collect! {|i| i * 2}

Array.map{|i|}:疊代陣列

1
2
3
4
5
6
7
8
9
10
arr = [1,2,3,4,5,6,7,8,9,0]
arr.map { |i| i * 2 } # [2, 4, 6, 8, 10, 12, 14, 16, 18, 0]

arr.map do |item|
item*2
end

arr.map do |item|
{name: item}
end

Array.each{|i|}:疊代陣列

1
2
3
4
5
arr = [1,2,3,4,5,6,7,8,9,0]

arr.each do |item|
puts item*2
end

Array.select{|i|}:篩選陣列中的內容(filter)

1
2
arr = [1, 2, 3, 4, 5, 6 ]
arr.select {|i| i % 2 == 0} # [2, 4, 6]

利用 Proc 轉換陣列裡的內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
##
# 將陣列內的數值轉成字串
##

number = [1,2,3,4,5]
string = number.collect(&:to_s) # ["1", "2", "3", "4", "5"]

##
# 將陣列內的字串轉成數值
##

string = ['1', '2', '3', '4', '5']
number = string.collect(&:to_i) # [1, 2, 3, 4, 5]
number = string.map(&:to_i) # [1, 2, 3, 4, 5]

陣列方法

select & reject

1
2
3
4
5
6
7
8
9
10
11
12
filter = [1,2]
target = [1,2,3,4,5]

# select: [1,2]
target = target.select do |item|
filter.include? item
end

# reject: [3,4,5]
target = target.reject do |item|
filter.include? item
end

其他技巧

根據特定目標排序

讓 arr 根據 target 的順序排序:

1
2
3
4
5
6
7
8
9
10
11
target = ['a', 'c', 'b']
arr = [{name: 'a'}, {name: 'b'}, {name: 'c'}]
arr_sort_by_target = []

arr.each do |item|
index = target.index(item[:name])
arr_sort_by_target[index] = item
end

puts arr_sort_by_target.inspect
# [{:name=>"a"}, {:name=>"c"}, {:name=>"b"}]

參考資料

Array @ Ruby-doc

掃描二維條碼,分享此文章