我有以下结构体,它们是根据Apple中的SwiftUI示例定义的。
struct Cat: Hashable, Codable, Identifiable {
let id: Int
let name: String
let audio: [Int]? // list of audio of cat sound
}
struct CatAudio: Hashable, Codable, Identifiable {
let id: Int
let filename: String
}
然后我想访问音频,然后在视图中传递。
我有这样的json数据:
[
{
"id": 55,
"name": "meow",
"audio": [6,5]
},
{
"id": 3,
"name": "meowmeow",
"audio": [2]
}
]
AudioData.json
[
{
"id": 5,
"filename": "5.wav"
},
{
"id": 2,
"filename": "2.wav"
},
{
"id": 6,
"filename": "6.wav"
}
]
json文件加载成功。
@Published var cats: [Cat] = load("CatData.json")
@Published var catAudios: [CatAudio] = load("CatAudio.json")
然后我尝试从我的环境模型数据中获取音频对象:
@EnvironmentObject var modelData: ModelData
,然后我想要得到猫对应的音频对象。但是我没有这样做,因为我不知道如何使用"id"。得到它。
的例子:
假设我从模型中获得了cat对象:
let cat = modelData.cats[0]
然后我想根据它的音频列表中存储的id获取它的音频数据
let catAudio = modelData.catAudios[cat.audio[0]!] // exception here
我发现是因为数组顺序可能与"Id"不一致。我想利用"id"而不是数组顺序来获取项目。我该怎么做呢?
========
我试着写一个函数来获取猫的CatAudio列表。我还将音频设置为非可选。
func getAudio(cat: Cat) -> [CatAudio] {
return cat.audio.compactMap{id in catAudio.filter { $0.id==id } }
}
但是它抱怨说不能将[CatAudio]类型的值转换为闭包结果类型'CatAudio'
我把它弄糊涂了。
您需要使用高阶函数来匹配audio
数组中的id值与CatAudio数组中的元素
假设有两个数组和一个选定的Cat对象
var cats: [Cat] = ...
var catAudios: [CatAudio] = ...
let cat = cats[0]
为一个id选择一个音频
if let firstId = cat.audio?.first {
let audio = catAudios.first { $0.id == firstId}
}
获取cat
对象的所有CatAudio的数组
if let array = cat.audio {
let values = array.compactMap { id in catAudios.filter { $0.id == id }}
}
如果audio
数组不是可选的,代码会更简单,有什么理由将其声明为可选的?