• 2

Swift交流討論區

ilbed wrote:
所以每次在練習寫程式...(恕刪)


前面的回文其實已經說得很清楚了,Swift 得 Dictionary 是無順序的,你放進去東西的順序跟它內部的排列沒有關聯也無相依性。如果你要用放進的順序列出,只能透過另外建立一個 Key 值的 Array 來一一作取出的動作才行。(在 Objective-C 也是得這樣做吧?只是更麻煩得用 keyEnumerator)

import Foundation

var i = 0
let keyArray = ["book", "Game", "iPhone"]
let shoppinglist = [
keyArray[i++] : [1,2,3,4,5],
keyArray[i++] : [10,20,30,40,50],
keyArray[i] : [100,200,300,400,500]
]

var lagter = 0
for key in keyArray {
for number in shoppinglist[key]! {
println(key , number)
if number > lagter{
lagter = number
}
println(lagter)
}
}

-----

(book, 1)
1
(book, 2)
2
(book, 3)
3
(book, 4)
4
(book, 5)
5
(Game, 10)
10
(Game, 20)
20
(Game, 30)
30
(Game, 40)
40
(Game, 50)
50
(iPhone, 100)
100
(iPhone, 200)
200
(iPhone, 300)
300
(iPhone, 400)
400
(iPhone, 500)
500

------

如果你很想偷懶,其實也可以把第一段改成:

let shoppinglist = [
"1_book" : [1,2,3,4,5],
"2_Game":[10,20,30,40,50],
"3_iPhone":[100,200,300,400,500]
]

這樣在這個範例中就會是你要的順序,但是前面說過了,這是不可靠的依據,真正要寫重要的東西時不要用。

順便一提,如果你有寫程式相關的問題,比起 Mobile01,StackOverflow 可能是更好的地方,那裏討論 Swift 的人其實不少。
http://vox.vg
ilbed wrote:
Apple本次發表會...(恕刪)


小弟沒研究 Swift,不過從你的執行結果來看,
Swift 的預設集合很明顯是一個 Unordered Hash。
會這樣設計理由也很簡單:速度。

像這種類型的關聯式集合大體上會使用的方法也就是兩種:list 或 hash。
list 就是依照你輸入的順序把一組一組資料一個串一個,
hash 則是先用 key 計算出一個索引值,然後依照索引把資料存在預先配置好的陣列的指定位置。
所以 hash 實際上佔用的記憶體會比較大,而加入新資料的速度也比 list 慢。

hash 最大的優點就是查詢速度快。
當你要用 key 來從集合中查詢一筆資料,
採用 list 的方式,必須從第一筆開始比對一路比到最後。
運氣好第一個就碰對,運氣不好要比對到最後一個才找到。
hash 則是把查詢 key 用相同方式計算索引,直接到陣列指定位置去找。
所以不管你的集合有多大,速度基本上都是常數。

hash 比較麻煩的是索引值碰撞,也就是兩個不同的 key 計算出相同索引值。
這時候就要把後來的向後順延佔據另一個位子,或是重新配置整個陣列,
這樣一來耗用時間就會比較多,因此 hash 整體來說寫入速度會比 list 慢。

所以說,如果你程式裡用到的集合資料量很大、然後需要頻繁的利用 key 來查詢,
使用 hash 可以有效提高反應速度。
如果所有的動作都只是表列,只有少數場合需要查詢,或是寫入遠比讀取頻繁,
那一開始就應該宣告成陣列,並且把 key 當成陣列內容結構的一部分。
其實我的感覺是學 Swift 還是要先學 Objective-C ,
因為 Swift 很多概念都是從這邊過來的,
像是樓主問的 Dictionary 與在 Objective-C 中的情況是一模一樣的,
Objective-C 的 Dictionary 不是無順序,其實它會依照 Key 值去排序,
所以我自己只是將它當做一個資料保存的手段,
取出的順序完全由我定義就是了。
我去查C#的Dictionary, 說其實是Hash Table的泛型版本。

應該說如果有排序也是以Hash值的方式來排序,而不是以加入的order來排序。

假設以前都認為Dictionary是依照加入的順序來排序,或是以key值來排序,
那都只是「碰巧」而已! 應該說如果你想做什麼,就要用對應的資料結構
去做,例如list一定是以加入順序做元素的排列順序。需要以key來索引值就用
Dictionary。
與失敗為伍者,天天靠盃都是別人的錯。 與成功為伍者,天天跟失敗切磋直到不再出錯。

小朱 wrote:
其實我的感覺是學 Swift 還是要先學 Objective-C ,
因為 Swift 很多概念都是從這邊過來的,
像是樓主問的 Dictionary 與在 Objective-C 中的情況是一模一樣的,
Objective-C 的 Dictionary 不是無順序,其實它會依照 Key 值去排序,
所以我自己只是將它當做一個資料保存的手段,
取出的順序完全由我定義就是了。



https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/CollectionTypes.html

Iterating Over a Dictionary裏的例子。

for (airportCode, airportName) in airports {
println("\(airportCode): \(airportName)")
}
// TYO: Tokyo
// LHR: London Heathrow

這跟你想的依key值排序結果一樣嗎?
與失敗為伍者,天天靠盃都是別人的錯。 與成功為伍者,天天跟失敗切磋直到不再出錯。
這部分跟Objective-C的NSDictionary完全是一樣的,如果希望照著順序排,要自己對Key做排序,再取出value

ilbed wrote:
所以每次在練習寫程式...(恕刪)


Objective-C簡易寫法

NSDictionary *shoppinglist = @{
@"book":@[@(1),@(2),@(3),@(4),@(5)],
@"Game":@[@(10),@(20),@(30),@(40),@(50)],
@"iPhone":@[@(100),@(200),@(300),@(400),@(500)]
};

NSNumber* lagter = @(0);

for (NSString* key in shoppinglist.allKeys)
{
for (NSNumber* number in shoppinglist[key])
{
NSLog(@"%@,%@",key,number);

if (number.intValue > lagter.intValue)
{
lagter = number;
}

NSLog(@"%@",lagter);
}
}

也許有更好的寫法
bluesystem wrote:
在https://d...(恕刪)


書中有提到,Swift 中 Dictionary 順序是沒有固定的,如果出來對只能說是「剛好」,難保不會出錯。

Objective-C 官方對於 Enumeration 的解釋:

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Collections/Articles/Enumerators.html

我個人是覺得會 Objective-C 的人轉 Swift 大概不用幾天就可以上手。


pin126916126916 wrote:
Objective-...(恕刪)


用 for 回圈跑的 Fast Enumeration 優點是速度比較快,缺點是會有 racing 的問題。如果你有多個 thread,在 Enumerating 的時候可能會因為另一個 thread 去讀寫同一個 Dictionary 而發生錯誤。如果用 NSEnumerator 做 Enumeration,程式中如果發生 racing 的情況就會被 LLVM 發現而出現 error 提示修正。
http://vox.vg

______ wrote:
書中有提到,Swif...(恕刪)


學習了,謝謝~

確實接觸過Objective-C的人轉到Swift的門檻不太高,重新適應一下語法寫法就可以了,只是看Obj-C的囉嗦寫法習慣了,看Swift程式碼還要先腦內轉換一下。
真的是學習了

本身沒碰過OBJ-C ,以前是學Java

所以對我來說大概只有寫程式的概念跟邏輯可以沿用

語法真的是完全重來!!感謝大大們的分享!
  • 2
內文搜尋
X
評分
評分
複製連結
Mobile01提醒您
您目前瀏覽的是行動版網頁
是否切換到電腦版網頁呢?