SQLite.Swift如何让随机行永不重复

时间:2017-12-20 23:14:44

标签: ios swift sqlite.swift

我正在iOS中尝试使用SQlite.Swift,而我正试图从SQLite数据库中的表中随机选择一行。

该表格为movies,其列为movieIDtitle genreseen

问题: 电影应该随机挑选,但一旦我将seen设置为“是”,就不应再挑选它们了。

func randomRow() -> Int {

       let path = NSSearchPathForDirectoriesInDomains(
                 .documentDirectory,
                 .userDomainMask, true)
                 .first!

       let database = try! Connection("\(path)/movies.sqlite3")

       var randomRow = Int(arc4random_uniform(UInt32(try!
                       database.scalar(movies.where(seen != "yes")
                       .select(movieID.distinct.count)))))

       while previousNumber == randomRow {
             randomRow = Int(arc4random_uniform(UInt32(try!
             database.scalar(movies.where(seen != "yes")
             .select(movieID.distinct.count)))))
           }
             previousNumber = randomRow
             return randomRow
   }

      let destRow = randomRow()

现在我想使用从表中捕获的随机行号来引导随机电影的titlegenrelet(“dispMovie”和“movieGenre” )输出到UITextField

          let path = NSSearchPathForDirectoriesInDomains(
                     .documentDirectory,
                     .userDomainMask, true)
                     .first!

          let database = try! Connection("\(path)/filme.sqlite3")

          for movie in try! database.prepare(
                            self.movies.where(
                            seen != "yes" && movieID == "\(destRow)")) {

dispMovie = movie[title]
movieGenre = movie[genre]
                }

    outputTextField.text = "\(dispMovie), \(movieGenre)"

此代码工作正常。唯一的问题是我的seen电影仍然会被曝光,因为我在随机行函数中有.count

我也试过用这个调用Raw SQLite:

let newMovie = try! database.scalar(
                    "SELECT title, genre FROM movies WHERE seen != yes
                    ORDER BY RANDOM() LIMIT 1") as! String

outputTextField.text = newMovie

但是这只显示标题而不是类型,并且无法在额外的行中查找类型,因为电影是从随机行中选取的。我试图在原始代码中引用电影标题,但这会使应用程序崩溃。

感谢您的帮助和提示。

2 个答案:

答案 0 :(得分:0)

没有圣诞节,直到完成!

经过几天思考并突然碰到墙壁,我想起了古老的while循环。事实证明这是有效的,所以我把它作为我自己问题的答案:

忘掉randomRow()。不需要这个。我首先关注了SQLite RAW,并继续使用scalar库中的whereselectSQLite.Swift。这终于让我这样:

发布我的整个UIViewController,以便您自己测试:

class TestView: UIViewController {

//Table
    let movies = Table("movies")

//Expressions
    let movieId = Expression<String>("ID")
    let movieTitle = Expression<String>("movieTitle")
    let genre = Expression<String>("genre")
    let seen = Expression<String>("seen")

//to find with database connection
    var randomMovie = String()
    var movieDetails = [String]()

//Array of all movies seen
    var seenMovies = [String]()

//TestLabel to check everything
    @IBOutlet weak var testLabel: UILabel!

    @IBAction func testButton(_ sender: Any) {

//Open database connection
        let path = NSSearchPathForDirectoriesInDomains(
            .documentDirectory, .userDomainMask, true
            ).first!

        let database = try! Connection("\(path)/movies.sqlite3")

//Check column "seen" and add all movie Titles to Array seenMovies        
        for movie in try! database.prepare(self.movies.where(seen == "yes")) {
            self.seenMovies.append(movie[movieTitle])
        }

//Select random row from movies Table with SQLite RAW as String
        self.randomMovie = "\(try! database.scalar("SELECT movieTitle FROM movies WHERE seen != yes ORDER BY RANDOM() LIMIT 1"))"

//Create Array of details for that randomly picked movie
//Use scalar, where and select to find details from the picked movie above
        self.movieDetails = ["\(randomMovie!)",
            "\(try! database.scalar(movies.where(movieTitle == "\(randomMovie!)").select(genre)))"]

//And here's the "unique" thing...
//while randomMovie is also an element in seenMovies, loop until it's not
        while seenMovies.contains("\(randomMovie!)") {
            randomMovie = "\(try! database.scalar("SELECT movieTitle FROM movies WHERE seen != yes ORDER BY RANDOM() LIMIT 1"))"
        }
//let testLabel show the results and see that no seen movie will be picked        
        testLabel.text = "\(details)\n\n\(erraten)"

//To prevent the Array from being appended over and over:
        self.seenMovies.removeAll()

        } 
    }

由于我仍然认为自己是初学者(在10月开始编码&#39; 17),如果可能,请随意优化。我所有的测试都进行得很顺利,当转向&#34;看到&#34;。

时,没有重复的电影

答案 1 :(得分:0)

找到了SQLite.Swift issue在2016年提交的解决方案。

DataArray