2024-08-28

【Kotlin】隨機取出指定筆數的記錄

題目:

有一含 1000 筆記錄的資料表 table1,要從中取出任意 100

在詢問 Google 的 Gemini、OpenAI 的 ChatGPT、Perplexity 的 Perplexity、微軟的 Copilot,多認識了一些類別及技巧,故做此筆記。


做法一:

  1.  
  2. val mScope = CoroutineScope(Job() + Dispatchers.IO)
  3. mScope.launch {
  4. val mDbHelper = SQLite(baseContext)
  5. var db = mDbHelper.readableDatabase
  6.  
  7. // 查詢本機資料庫有幾筆記錄
  8. var sSql = "SELECT * FROM table1 "
  9. val rs = db.rawQuery(sSql, null)
  10. val mRecnt = rs.count // 本機資料庫記錄筆數
  11. var mSentence = 100 // 迴圈數, 要取出 100 筆記錄
  12.  
  13. val mList = mutableListOf<Int>()
  14. var xx = 1
  15. // 這種做法, 有可能亂數取得的 mPos 已存在 mList 中
  16. while(xx<=mSentence) {
  17. val mPos = (0 until mRecnt).random() // 每筆記錄在 table1 的位置
  18. if(mPos !in mList) {
  19. mList.add(mPos)
  20. xx++
  21. }
  22. }
  23. mList.sorted() // 將 mList 內的元素由小到大排序
  24. // 如此, 在實際自 table1 取出記錄就會是自資料表首一路向資料表尾依序取出記錄
  25. ...
  26. ...
  27. }
  28.  



做法二:

  1.  
  2. val mScope = CoroutineScope(Job() + Dispatchers.IO)
  3. mScope.launch {
  4. ...
  5. ...
  6.  
  7. val mRaw = mutableSetOf<Int>() // mutableSet 的特性是存入時就會檢查每個元素的值都是唯一
  8. val mRandom = Random(System.currentTimeMillis())
  9. while(mRaw.size<mSentence) {
  10. mRaw.add(mRandom.nextInt(mRecnt))
  11. }
  12. // 但 mutableSet 不具排序功能,
  13. // 故將它轉型態成 list 並排序後存入 mList
  14. val mList = mRaw.toList().sorted()
  15. ...
  16. ...
  17. }
  18.  



做法三:

  1.  
  2. val mScope = CoroutineScope(Job() + Dispatchers.IO)
  3. mScope.launch {
  4. ...
  5. ...
  6.  
  7. // 這個做法最快, 一行指令搞定
  8. // 以 shuffled() 洗牌後, 再以 take() 取前面幾個元素, 再將元素排序
  9. // (0 until mRecnt) 是 IntRange
  10. val mList = (0 until mRecnt).shuffled().take(mSentence).sorted()
  11. // val mList = (0 until mRecnt).shuffled(Random(System.currentTimeMillis())).take(mSentence).sorted() // 可以在 shuffled() 內加上時間當做亂數種子, 增強其隨機性
  12. ...
  13. ...
  14. }
  15.  
  1.  



沒有留言:

張貼留言