2017-12-20 7 views
1

私はiOSでSQlite.Swiftを試していますが、SQLiteデータベースのテーブルからランダムに行を選択しようとしています。SQLite.Swiftランダムな行を繰り返さない方法

テーブルがmoviesであり、その列はmovieIDtitlegenre及びseenです。

問題: ムービーはランダムに選択する必要がありますが、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() 

は今、私はUITextFieldに出力するlet(「dispMovie」と「movieGenre」)にランダム映画のtitlegenreをリードし、テーブルからcatchedされるように、このランダムな行番号を使用します。

  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を持っているので、まだ再生されているということです。

私も、このいずれかで生のSQLiteを呼び出すようにしようとしました:映画があるので

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

outputTextField.text = newMovie 

しかし、これだけタイトルを表示しないジャンルや余分な行のジャンルを探していることはできませんランダムな行から選択します。私はRawコードで映画のタイトルを参照しようとしましたが、それはアプリをクラッシュさせます。

ご協力ありがとうございます。

答えて

0

これが完了するまで、クリスマスはありません!

突然壁に向かって思考して走ってしまったあと、良い古いwhileループが私の心に浮かんだ。それは働いていたので私は自分自身の質問に対する答えとしてこれを残しています:

randomRow()を忘れました。これの必要はありません。私は最初にSQLite RAWに焦点を当て、SQLite.Swiftライブラリのscalar,whereおよびselectの組み合わせで続けました。私はまだ自分自身(10月'17でのコーディングを開始)初心者考えるので、可能な場合、これを最適化すること自由に感じなさい

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() 

     } 
    } 

:あなた自身をテストできるように

は私の全体のUIViewControllerを投稿:それは最終的に私はこれを得ました。私のテストはすべてうまくいっていて、「見た」と言えば何の映画も繰り返されませんでした。

+0

今日のテストセッションから少し確認:このコードを150回映画で3回テスト(3 * 150、3つの映画;-))しないでください。すべてうまく動作します。 「見た」映画は再び表示されませんでした。 – Aeger

関連する問題