过滤字典并更改其属性

时间:2018-11-26 08:01:15

标签: swift dictionary filter

我有一组字典var songsByLetters = [(key: String, value: [Song])](),并且用户选择了一首歌曲,他会将其放入收藏夹中。因此,我需要将选定的歌曲id isFaved布尔值更改为true

在我之前,没有歌曲首字母的歌曲对象数组作为新字典的键。当用户点击“收藏夹”按钮时,我曾经这样做。

@IBAction func favButtonTapped(_ sender: UIButton) {
   dbSongs.filter({$0.id == selectedSongId}).first?.isFaved = sender.isSelected
}

现在,由于我有词典,我正在尝试执行此操作,但这不仅是正确的方法,而且我当然会出错。

  

无法转换类型为(()的值?”关闭结果类型“布尔”

songsByLetters.filter{$0.value.filter{$0.id == selectedSongId}.first?.isFaved = sender.isSelected}

我了解错误,但我不知道如何过滤该词典并更改该特定歌曲isFaved的{​​{1}}属性

这是歌曲的结构:

id

3 个答案:

答案 0 :(得分:1)

并非只保留id,而是保留整个Song

var selectedSong : Song?

...

self.selectedSong = songsByLetters[indexPath.section].value[indexPath.row]

最有效的解决方案是将Song声明为具有引用语义的类,那么您根本不需要进行过滤

@IBAction func favButtonTapped(_ sender: UIButton) {
    selectedSong?.isFaved = sender.isSelected
}

注意:不鼓励您使用元组(您的 dictionary 实际上是元组)作为数据源。

答案 1 :(得分:0)

//首先您可以过滤对象

let filtered = dbSongs.filter({$0.id == selectedSongId}).first

//然后从列表中删除

let index = dbSongs.index { $0.id == filtered.id }

  if let index = index {
        let removed = dbSongs.remove(at: index) // Remove item
  }

//更新详细信息

removed.isFaved = true

//最终插入列表。

dbSongs.insert(removed, at index)

答案 2 :(得分:0)

我猜下面的代码有效

  struct Song {
        let id: Int
        let name: String
        let artist: String
        var isFaved: Bool
        let code: String
    }

    var songsByLetter: [String: [Song]] = ["H" : [Song(id: 2134, name: "Happy Birthday", artist: "Paul Anka", isFaved: false, code: "380dj0a"),Song(id: 38304, name: "How can i stop loving you", artist: "Savage Garden", isFaved: false, code: "kkdj0a")]]



    let selectedSongId = 38304
    var songs = songsByLetter.values.map({$0.filter({$0.id == selectedSongId})})

    if let songByH = songs.first, var song = songByH.first
    {
        song.isFaved = true
        let firstLetter = String(song.name.first ?? "0")
        let index = songsByLetter[firstLetter]?.firstIndex(where: {$0.id == selectedSongId})
        if let index = index
        {
            (songsByLetter[firstLetter])?.remove(at: index)
            songsByLetter[firstLetter]?.insert(song, at: index)
        }
    }

    print(songsByLetter)