【问题标题】:Populate UITableView with Sections用部分填充 UITableView
【发布时间】:2018-12-15 11:04:58
【问题描述】:

我正在尝试用部分填充 TableView。其中艺术家是部门名称,该艺术家的所有歌曲都在下面列出。共有100多名艺术家。像这样

FirstArtist
- Song 1
- Song 2

SecondArtist
 - Song 1
 - Song 2

OneMoreArtist...

我有一个对象数组 Song

struct Song {

  let songName: String?
  let album: String?
  let artist: String?

}

var songs = [Song]()

以及所有艺术家姓名的数组

var artists = [String]()

据我了解,要使用部分填充 tableView,我需要一个以 Artist 作为键并以歌曲数组作为值的字典,就像这样

var toShow = [String : [Song]]()

那么,我正在尝试循环

    for artist in artists {
      for song in songs {
        if song.artist == artist {

          toShow[artist] = [song]

//          toShow[artist]?.append(song)

        }
      }
    }

但它不起作用。

可能我走错路了。

这种情况有什么解决办法?

谢谢

更新

做了一个结构

    struct ArtistWithSongs  { 
       let name: String
       let songs: [Song]

        init(name: String, songs: [Song]) {
      self.name = name
      self.songs = songs
    }   
}

并试图循环

var artistWithSongs = [ArtistWithSongs]() 

     for artist in artists {
          for song in songs {
            if artist == song.artist {
              artistWithSongs.append(ArtistWithSongs(name: song, songs: [song]))
            }
          }
        }

但显然,我的循环变体是不正确的。现在我得到一个包含重复键的对象数组,每个键只有一首歌曲。好像

[Atrist1 : [Song1], Artist1 : [Song2], Artist1 : [Song3], ...]

我的问题是 - 制作循环的正确方法是什么,或者是否有可能以某种方式将具有相同键的对象合并到字典中以获取 [Artist1 :[Song1, Song2, Song3]]?

【问题讨论】:

    标签: arrays swift uitableview dictionary


    【解决方案1】:

    感谢大家,我找到了解决方案here,它对我想要实现的目标有效。大概是这样的

    let toShow = artistWithSongs.reduce([ArtistWithSongs](), { partialResult, artist in
    
        var dupe = partialResult.filter {$0.songName == group.name }.first
        if let dupeArtist = dupe {
            dupeArtist.songs?.append(contentsOf: artist.songs ?? [])
            return partialResult
        } else {
            var newPartialResult = partialResult
            newPartialResult.append(group)
            return newPartialResult
        }
    })
    

    【讨论】:

      【解决方案2】:

      如果您想将一组歌曲 ([Song]) 转换为字典 ([String : [Song]]),我建议使用函数式样式:

      self.toShow = songs.reduce([String: [Song]]()) { acc, next in
        // mutable copy
        var acc = acc
      
        // since artist is optional we need to substitute it with non-optional value if it's nil
        let artist = next.artist ?? "Unknown Artist"
      
        // if dictionary already has this artist, then append the `next` song to an array
        if acc[artist] != nil {
          acc[artist]?.append(next)
        } else {
        // otherwise create new array
          acc[artist] = [next]
        }
      
        return acc
      }
      

      在表格的数据源中提供部分的数量:

      func numberOfSections(in tableView: UITableView) -> Int {
        return self.toShow.keys.count
      }
      

      然后您将面临一个麻烦:对于部分中的行数,您需要知道该部分代表哪个艺术家。所以,我建议你使用更多的结构,一组艺术家,这样你就可以保持部分的顺序一致:

      self.artists = Array(self.toShow.keys).sorted()
      

      这样,您可以为表格提供以下部分和行数:

      func numberOfSections(in tableView: UITableView) -> Int {
        return self.artists.count
      }
      
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let artist = self.artists[section] // get the artist's name
        return self.toShow[artist]?.count ?? 0
      }
      

      【讨论】:

        【解决方案3】:

        除了你的Song 结构

        struct Song {
          let songName: String?
          let album: String?
        }
        

        创建Artist一个赞

        struct Artist { 
           let name:String
           let songs = [Song]()
        }
        

        然后创建一个数组

        var artists = [Artist]()
        let s1 = Song(songName:"name1",album:"alb1")
        let s2 = Song(songName:"name2",album:"alb2")
        let artist1 = Artist(name:"art",songs:[s1,s2])
        artists.append(artist1)
        

        在numberOfSections返回

        artists.count
        

        在numberOfRows返回

        artists[section].songs.count 
        

        在cellForRowAt访问

        let song = artists[indexPath.section].songs[indexPath.row]
        

        【讨论】:

        • 对不起,我之前没有提到,我有很多艺术家,所以无法手动将每个艺术家添加到 [Artist] 数组中。还是我误解了您的解决方案?
        • 谢谢,但我问是因为显然我的循环变体不正确。现在我得到一个包含重复键的对象数组,每个键只有一首歌曲。它看起来像 [Atrist1:[Song1],Artist1:[Song2],Artist1:[Song3],...]。我的问题是 - 如何正确地创建一个循环,或者是否有可能以某种方式在字典中合并具有相同键的对象以获得这个 [Artist1 :[Song1, Song2, Song3]]?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多