如何确定数组是否已包含值以及是否跳转到下一个值?

时间:2017-02-02 22:45:30

标签: ios arrays swift

目前我有一个更新一些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
              })
          })
        }

      })
    }

3 个答案:

答案 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中做到这一点:

  1. 最初使用Set而不是数组,并且最后只返回从集合中创建的数组:

    让posterArray = Array(posterSet) 完成(posterArray)

  2. 保留一个数组,最后清楚重复(例如,通过转换为set和back,或者还有其他方法,例如contains-append)

  3. 使用套装会让你失去顺序。

    从您发布的代码中,海报数组似乎总是有一个项目。我是否正确理解了您要实现的目标?

答案 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]