目前我有一个更新一些ui(电影类别)的功能。它从json获取ui数据并根据json给出的url字符串更新图像。返回的json数据是一个数组,因此我目前正在做的是获取该数组中的第一个元素并将其用于ui。唯一的问题是我注意到数组中的第一个json数据对多个类别使用相同的图像字符串。
我尝试做的是检查数组是否包含当前字符串,如果它确实跳到下一个字符串,直到它到达不在数组中的字符串。到达此字符串时,将其附加到数组。这是我到目前为止所拥有的 -
这是我用来更新检索到的json信息的函数:
static func updateGenrePoster(genreID: NSNumber, urlExtension: String, completionHandler:@escaping (_ details: [String]) -> Void){
var posterArray: [String] = []
let nm = NetworkManager.sharedManager
nm.getJSONData(type:"genre/\(genreID)", urlExtension: urlExtension, completion: {
data in
if let jsonDictionary = nm.parseJSONData(data)
{
guard let genrePoster = ResultsGenrePosters(json: jsonDictionary)
else {
print("Error initializing object")
return
}
guard let posterString = genrePoster.results?[0].poster//This is where I want to check to see if array already contains the string
else {
print("No such item")
return
}
posterArray.append(posterString)
}
completionHandler(posterArray)
})
}
这是我用来更新ui的函数:
func updateUI()// updates Tableview IBOutlets
{
if let genreID = genreData.id {
GenrePosters.updateGenrePoster(genreID: genreID, urlExtension: "movies", completionHandler: {posters in
for poster in posters{
self.networkManager.downloadImage(imageExtension: "\(poster)",
{ (imageData) //imageData = Image data downloaded from web
in
let image = UIImage(data: imageData as Data)
DispatchQueue.main.async(execute: { //Must update UI on main thread so have to get main queue
self.genreCatagoryLabel.text = self.genreData.name
self.mainImageView.image = image
})
})
}
})
}
答案 0 :(得分:0)
一个简单的解决方法是使用Set。当您正在浏览阵列时,只需执行类似的操作(大约代码,我没有尝试语法):
if mySet.Contains(the_current_string)
{
// skip this one since it's a dupe
continue
}
else
{
mySet.Append(the_current_string)
}
编辑:我已经冒昧地拼写出来,因为我原来的帖子似乎含糊不清。
func pointlessMethod()
{
let arrayOfStrings = ["a", "b", "a", "c", "a", "d"]
var mySet: Set<String> = []
for someString in arrayOfStrings
{
if mySet.contains(someString)
{
continue
}
else
{
mySet.insert(someString)
}
// Do the stuff you want to do with the non-dupe
}
}
答案 1 :(得分:0)
看来你要做的就是让数组中所有不同的字符串只加载一次图像。
你可以通过几种方式在swift中做到这一点:
最初使用Set
而不是数组,并且最后只返回从集合中创建的数组:
让posterArray = Array(posterSet) 完成(posterArray)
保留一个数组,最后清楚重复(例如,通过转换为set和back,或者还有其他方法,例如contains-append)
使用套装会让你失去顺序。
从您发布的代码中,海报数组似乎总是有一个项目。我是否正确理解了您要实现的目标?
答案 2 :(得分:0)
你可以编写一个函数来获取一个String对象数组,并返回一个结果数组,其中包含字符串源数组中的第一个唯一元素:
func uniqueElementsFrom(array: [String]) -> [String] {
var set = Set<String>()
let result = array.filter {
guard !set.contains($0) else {
return false
}
set.insert($0)
return true
}
return result
}
let arrayOfStrings = ["a", "b", "a", "c", "a", "d"]
let uniqueStrings = uniqueElementsFrom(array:arrayOfStrings)
print("Unique elements from \(arrayOfStrings) = \n \(uniqueStrings)")
该代码使用Set
来跟踪数组中的唯一元素。它使用Swift filter
函数,该函数采用闭包。 (filter命令之后的大括号中的代码。)闭包从数组中获取一个元素作为唯一参数,如果元素应该包含在结果数组中,则返回true
,或{{ 1}}如果应该跳过它。
该函数产生输出:
来自[&#34; a&#34;,&#34; b&#34;,&#34; a&#34;,&#34; c&#34;,&#34; a&#34的独特元素;,&#34; d&#34;] =
[&#34; a&#34;,&#34; b&#34;,&#34; c&#34;,&#34; d&#34;]
更好的是,您可以重写false
函数以获取符合Hashable协议的任何元素的数组。为此,您使用泛型。
下面是重写的uniqueElementsFrom(array:)
函数,用于处理对象为uniqueElementsFrom(array:)
的任何对象数组
Hashable
函数名称后的func uniqueElementsFrom<T: Hashable>(array: [T]) -> [T] {
var set = Set<T>()
let result = array.filter {
guard !set.contains($0) else {
return false
}
set.insert($0)
return true
}
return result
}
位表示&#34;此函数的其余部分将引用未指定的类型T.您唯一可以确定的是T类型符合<T: Hashable>
协议。&#34;
因此,如果您传入Hashable
个数组,则标题和函数正文中String
的所有提及都将替换为T
该函数的新版本提供与先前版本完全相同的输出,但只要该类型为String
,您就可以向其传递包含任何类型对象的数组。
所以你可以像这样轻松地使用这个函数:
Hashable
你得到输出
来自[1,3,17,9,1,17,3,4]的独特元素=
[1,3,17,9,4]