2024-08-28

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

題目:

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

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


做法一:

 
val mScope = CoroutineScope(Job() + Dispatchers.IO)
mScope.launch {
    val mDbHelper = SQLite(baseContext)
    var db = mDbHelper.readableDatabase

    // 查詢本機資料庫有幾筆記錄
    var sSql = "SELECT * FROM table1 "
    val rs = db.rawQuery(sSql, null)
    val mRecnt = rs.count    // 本機資料庫記錄筆數
    var mSentence = 100   // 迴圈數, 要取出 100 筆記錄

    val mList = mutableListOf<Int>()
    var xx = 1
    // 這種做法, 有可能亂數取得的 mPos 已存在 mList 中
    while(xx<=mSentence) {
        val mPos = (0 until mRecnt).random()    // 每筆記錄在 table1 的位置
        if(mPos !in mList) {
            mList.add(mPos)
            xx++
        }
    }
    mList.sorted()    // 將 mList 內的元素由小到大排序
    // 如此, 在實際自 table1 取出記錄就會是自資料表首一路向資料表尾依序取出記錄
    
    ...
    ...
}
 



做法二:

 
val mScope = CoroutineScope(Job() + Dispatchers.IO)
mScope.launch {
    ...
    ...

    val mRaw = mutableSetOf<Int>()    // mutableSet 的特性是存入時就會檢查每個元素的值都是唯一
    val mRandom = Random(System.currentTimeMillis())
    while(mRaw.size<mSentence) {
        mRaw.add(mRandom.nextInt(mRecnt))
    }
    // 但 mutableSet 不具排序功能, 
    // 故將它轉型態成 list 並排序後存入  mList
    val mList = mRaw.toList().sorted()
    
    ...
    ...
}
 



做法三:

 
val mScope = CoroutineScope(Job() + Dispatchers.IO)
mScope.launch {
    ...
    ...

    // 這個做法最快, 一行指令搞定
    // 以 shuffled() 洗牌後, 再以 take() 取前面幾個元素, 再將元素排序
    // (0 until mRecnt) 是 IntRange
    val mList = (0 until mRecnt).shuffled().take(mSentence).sorted()
    // val mList = (0 until mRecnt).shuffled(Random(System.currentTimeMillis())).take(mSentence).sorted()   // 可以在 shuffled() 內加上時間當做亂數種子, 增強其隨機性
    
    ...
    ...
}
 



沒有留言:

張貼留言