按ID访问数据对象



我有以下结构体,它们是根据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数组不是可选的,代码会更简单,有什么理由将其声明为可选的?

最新更新