2017-02-12 9 views
0

に割り当てるようにしました。私はSpotifyのAPIを試していましたが、これまでに経験した中で最も複雑な問題に遭遇しました。私はジャンルのテキストファイルを持っています。 "チル"または "ハウス"。これらのファイルには、Spotify-Playlistsへのリンクがあります。これらの行の最初例えば、このジャンルのプレイリストを表します。:今すぐPlaylist-Trackを3D配列

myplalyist-ID 
random1-ID 
random2-ID ... 

これらのリンクは、プレイリストを指しているので、それらのプレイリストはトラックが含まれています。今、私はこれらのランダムなプレイリストからすべてのトラックを取得し、それを私の中に収めたいと思います(トラックを追加したり追加することはここでは問題ではありません)。 は、今私は例えば、私はそれらのトラックを処理するための3Dアレイを作成したと考えていた:

1D: genre1 - genre2 - genre3 
2D: playlist1 - playlist2 - playlist3 
3D: tracks1 - tracks2 - tracks3 

私はplaylisttracksにアクセスできるようにしたい、あなたは私が何を意味するか理解してほしい、このような何かを谷:

foreach(PlaylistTrack track in array[genre][playlist]) 
    // filter & add "track" 
私は完全にこれに迷ってしまいましたので、

//PlaylistTrack is the type in which Spotify stores a track within a Playlist 
private List<PlaylistTrack>[,,] playlistTracks;//3D??? 
//this is to store the amount of playlists within a genre 
private int[] playlistArray; 
//int to save the amount of genre-files 
private int fileCount; 

//-----------------METHOD: 

private void getTracks() 
{ 
    DirectoryInfo dir = new DirectoryInfo(this.path);//directory where genres are stored 

    this.fileCount = 0; 

    foreach (var file in dir.GetFiles("*.txt")) 
    { 
     if (file.Name != "My Tracks.txt" && file.Name != "Tracks.txt")//getting all genre textfiles 
     { 
      this.fileCount++; 
     } 
    } 

    this.playlistArray = new int[this.fileCount]; 

    //i know using the foreach over and over is kinda bad and not preofessional, 
    //but i don't use c# on a daily base and i didn't knew how to get it done otherwise 

    int count = 0; 
    foreach (var file in dir.GetFiles("*.txt")) 
    { 
     if (file.Name != "My Tracks.txt" && file.Name != "Tracks.txt") 
     { 
      int count2 = 0; 
      if (File.ReadAllText(file.FullName) != "") 
      { 
       using (StreamReader sr = new StreamReader(file.FullName)) 
       { 
        string line = ""; 
        while ((line = sr.ReadLine()) != null) 
        { 
         if (line != "") 
         { 
          count2++; 
         } 
        } 
       } 

      } 
      this.playlistArray[count] = count2; 
      count++; 
     } 
    } 

    for (int i = 0; i < this.fileCount; i++) 
     this.playlistTracks[i] = new List<PlaylistTrack>[this.playlistArray[i]](); 
    //here i'm stuck, how would i initialize the array, so it can holds a bunch of PlaylistTrack Items in "3rd row", 
    //accessable through [genre][playlist] 
} 

すべてのヘルプは大幅に高く評価され、次のよう

だから、これまで私のアプローチでした! :)

EDIT: 私が試したものです:私はコードでそれをマークどこ

//Setting File-Count to 0 
this.fileCount = 0; 

//Init new Dictionary 
var allTracks = new Dictionary<string, Dictionary<string, List<PlaylistTrack>>>(); 

//Getting Directory where Genre-Files are 
DirectoryInfo dir = new DirectoryInfo(this.path); 

int count = 0; 
//Looping through files in this Directory #1 
foreach (var file in dir.GetFiles("*.txt")) 
{ 
    //Get only Genre-Files, not Track-Lists 
    if (file.Name != "My Tracks.txt" && file.Name != "Tracks.txt") 
    { 
     count++; 
    } 
} 

//Init new string Array that will hold the Links to my Playlist for every genre 
this.playlistLinks = new string[count]; 

//Looping through files in this Directory #2 
foreach (var file in dir.GetFiles("*.txt")) 
{ 
    //Get only Genre-Files, not Track-Lists 
    if(file.Name != "My Tracks.txt" && file.Name != "Tracks.txt") 
    { 
     //If the Genre-File has content 
     if (File.ReadAllText(file.FullName) != "") 
     { 
      //Getting the Genre Name, by splitting the Genre-File-Name 
      string name = file.Name.Split(new string[] { ".txt" }, StringSplitOptions.None)[0]; 

      //Reading the Genre-File 
      using (StreamReader sr = new StreamReader(file.FullName)) 
      { 
       string line = ""; 
       bool first = false; 
       //If the new line has content 
       while ((line = sr.ReadLine()) != null) 
       { 
        //If it's not the first line and the line is not "" 
        if (first && line != "") 
        { 
         //Splitting line to get Data 
         //split[0] = PlaylistID; split[1] = OwnerID 
         string[] split = line.Split(new string[] { " // " }, StringSplitOptions.None); 
         //Getting Playlist Tracks and storing them in the Dictionary 
         //HERE HAPPENS THE ERROR 
         allTracks[name][split[0]] = this.getPlaylistTracks(split[1], split[0]); 

         //Looping through the Playlist-Tracks within the Dictionary 
         foreach (PlaylistTrack tr in allTracks [name][split[0]]) 
         { 
          //If the Track is on Spotify's Servers 
          if (!tr.IsLocal) 
          { 
           //Filtering (not important here -> does work) 
           if (tr.AddedAt > time) 
           { 
            //Creating a string that holds Track's info 
            string write = tr.Track.Name + " // " + string.Join(",", tr.Track.Artists.Select(source => source.Name)); 
            //Filtering tracks that i haven't listened to, by checking if track exists in "My Tracks.txt" 
            //(not important here -> does work) 
            if (!this.foundTrack(write)) 
            { 
             //Adding collected Tracks to another List, sorted by Genre 
             //So all filtered Tracks from all Playlists within a genre are stored in one list 
             this.tracksToAdd[this.fileCount].Add(tr); 
            } 
           } 
          } 
         } 
        } 
        //If it's the first line where the line is not "" 
        if(!first && line != "") 
        { 
         string[] split = line.Split(new string[] { " // " }, StringSplitOptions.None); 
         //Getting the PlaylistID of my Playlist 
         this.playlistLinks[this.fileCount] = split[0]; 
         first = true; 
        } 
       } 
      } 
     } 
     //Increasing on every new Genre-File 
     this.fileCount++; 
    } 
} 

エラーは、発生します。エラー・メッセージは以下のとおりであった:

A "System.Collections.Generic.KeyNotFoundException" の例外が はがmscorlib.dllで発生しました。追加情報:指定されたキー は辞書に指定されていません。 (おおよそドイツ語から翻訳)

答えて

1

各プレイリストは、曲の異なる数を有することができるので、あなたが固定サイズの3Dマトリックス([,,,])が、配列の配列([][][])を必要としません。あなたはそれらの違いをthis questionで読むことができます。

言われているように、あなたはPlayListTrack[][][]を使ってあなたが望むものを達成することができます。 var allTracks = new PlayListTrack[amountOfGenres][][];のようなものを作成し、allTracksの各行をPlayListTrack[][]として初期化します。そのサイズは、その行に一致するジャンルの再生リストの量です。最後に、各プレイリストをPlayListTrack[]として初期化することができます。そのサイズは、指定されたプレイリストの曲の量です。

とにかく、私はDictionary<TKey, TValue>クラスを見てみることをお勧めします。このクラスでは、固有のキー(ジャンルのIDなど)を値(たとえばプレイリストなど)にマッピングできます)。

// Lists of tracks, indexed by their genre id (first string) and 
// their playlist id (second string) 
var allTracks = new Dictionary<string, Dictionary<string, List<PlayListTrack>>>(); 

// Examples 

// Getting a genre, which is a Dictionary<string, List<PlayListTrack>> 
var allJazzPlayLists = allTracks["jazz"]; 

// Getting a list of songs, which is a List<PlayListTrack> 
var songs = allTracks["hip-hop"]["west side"]; 
+0

おかげで、素晴らしい答え:

次に、あなたのようなものを持っている可能性が!私はこれが私が探しているものだと思います。私はOPで試したコードを追加しました:たぶん、あなたはそれを見て、そのエラーが発生する理由と私はそれを修正する方法を教えてください。 –

+0

あなたのエラーは、 'allTracks [name] [split [0]]'は存在しないallTracks [name] 'を取得しようとするために発生します。その行の前に、ネストされたディクショナリが存在しなければ作成するべきです: 'if(!(allTracks.ContainsKey(name)){allTracks [name] =新しい辞書>();} ' 'getPlaylistTracks(string、string)'メソッドが 'List()'を返すと仮定して、 'allTracks [name] [split [0]] = this.getPlaylistTracks(split [1]、split [0]); ' – Sam