There is a class with two variables for defining an array

import Foundation class AddClass: NSObject, NSCoding{ var name500: String var date500: String init(name500:String, date500:String) { self.name500 = name500 self.date500 = date500 } func encode(with aCoder: NSCoder) { aCoder.encode(name500, forKey: "name500") aCoder.encode(date500, forKey: "date500") } required init?(coder aDecoder: NSCoder) { self.name500 = aDecoder.decodeObject (forKey: "name500") as! String self.date500 = aDecoder.decodeObject (forKey: "date500") as! String } } 

There are two arrays defined by the class in which to write data from ordinary arrays of type String

 var names: [AddClass] = [] var dates: [AddClass] = [] 

These two arrays of type String get the values ​​from the parsing and look like this:

  nameGame500 = ((url.object(forKey: "links") as! NSArray).value(forKeyPath: "name") as! NSArray) as! [String] dategame500 = ((url.object(forKey: "links") as! NSArray).value(forKeyPath: "release_date") as! NSArray) as! [String] 

Need to do what would

 var names: [AddClass] = [] был равен nameGame500 var dates: [AddClass] = [] был равен dategame500 

This method works only if there is one variable in the class.

 names = nameGame500.map({ AddClass(name500: $0) }) 

but if two

 names = nameGame500.map({ AddClass(name500: $0) }) dates = dategame500.map({ AddClass(date500: $0) }) 

it gives an error

 'map' produces '[T]', not the expected contextual result type '[AddClass]' 

UPD:

 let ss = names.map {names -> [Image] in let arrayImage = names.images let sv = arrayImage.filter {arrayImage -> Bool in let typeUrl = arrayImage.type return typeUrl == 1 } return sv } 
  • You need to initialize the second variable during the mapping too. Something similar to do: AddClass (name500: $ 0, secondName: "") - Vitaly
  • so it will not work out exactly, because I map the array in which, for example, the names are sparred, but there is an array with dates, and it needs to be separately mapped, because of this, the error pops up - Vladislav Bublik
  • Then add a more complete description, that you have a second array and you want to create an array of objects based on the data of the arrays. - Vitaly
  • Well, it was originally written) I thought it was clear, now I will correct it - Vladislav Bublik
  • I fixed the post, I think now everything is clear - Vladislav Bublik

3 answers 3

I would do that

 class AddClass: Decodable { var name500: String var date500: String private enum CodingKeys: String, CodingKey { case name500 = "name" case date500 = "release_date" } required init(from decoder: Decoder) throws { let conteiner = try decoder.container(keyedBy: CodingKeys.self) name500 = try conteiner.decode(String.self, forKey: .name500) date500 = try conteiner.decode(String.self, forKey: .date500) } } 

And structure for parsing JSON

 struct Response: Decodable { var addClasses: [AddClass] private enum CodingKeys: String, CodingKey { case addClasses = "links" } init(from decoder: Decoder) throws { let conteiner = try decoder.container(keyedBy: CodingKeys.self) addClasses = try conteiner.decode([AddClass].self, forKey: .addClasses) } } 

For objects

  let decoder = JSONDecoder() do { let response = try decoder.decode(Response.self, from: data) // data: Data response.addClasses // -> [AddClass] вот наш масив } catch let error { print("decoding error: \(error)") } 

UPD : for pictures you can do this

Create a class for pictures

  class Image: Decodable { var type: Int var url: URL private enum CodingKeys: CodingKey { case type case url } required init(from decoder: Decoder) throws { let conteiner = try decoder.container(keyedBy: CodingKeys.self) type = try conteiner.decode(Int.self, forKey: .type) let urlString = try conteiner.decode(String.self, forKey: .url) url = URL(string: urlString)! } } 

and add the field to the AddClass

  class AddClass: Decodable { var name500: String var date500: String var images: [Image] private enum CodingKeys: String, CodingKey { case name500 = "name" case date500 = "release_date" case images } required init(from decoder: Decoder) throws { let conteiner = try decoder.container(keyedBy: CodingKeys.self) name500 = try conteiner.decode(String.self, forKey: .name500) date500 = try conteiner.decode(String.self, forKey: .date500) images = try conteiner.decode([Image].self, forKey: .images) } } 

UPD: If it’s still difficult to do this, when you already have 2 arrays you simply create an object based on them:

 for (index, name500) in nameGame500.enumerated() { var game500 = dategame500[index] let addClass = AddClass(name500: name500, game500: game500) result.append(addClass) } 

UPD: here, get url pictures for any type through calling myAddClassObject.getImageUrl(for: 1) method myAddClassObject.getImageUrl(for: 1)

 class AddClass: Decodable { var name500: String var date500: String var images: [Image] private enum CodingKeys: String, CodingKey { case name500 = "name" case date500 = "release_date" case images } required init(from decoder: Decoder) throws { let conteiner = try decoder.container(keyedBy: CodingKeys.self) name500 = try conteiner.decode(String.self, forKey: .name500) date500 = try conteiner.decode(String.self, forKey: .date500) images = try conteiner.decode([Image].self, forKey: .images) } func getImageUrl(for type: Int) -> URL? { let image = images.first{ return $0.type == type } return image?.url } } 
  • already solved the problem, but I will try and your way too) maybe I can pull the pictures from json, otherwise I can do everything except for links to pictures))) - Vladislav Bublik
  • those. We received the data from Parsing in response.addClasses? and how then to use it, should it be name and date? - Vladislav Bublik
  • Well, there is an array of objects, each has a name, date, and a set of pictures. All of that link that you threw, there seems to be 5-7 pictures for each record - Andrey Iskamov
  • Yes, about the pictures correctly, I had problems with that, pull out one picture from the set But I ask how to use the data we received later. I bring them to the table, but I don’t quite understand how to do it) apparently I’m already jumping over my head) - Vladislav Bublik
  • Well, you can filter by the type of picture (I don’t know which one you need) and then download it by link and that's it - Andrey Iskamov

In theory, so let convertedArray = arrayForPars.map({ AddClass(name: $0) })

  • It does not work out, I tried about the same, and everything is in vain) - Vladislav Bublik
  • But no, it worked, I was a little wrong with the array poking)) came from the night shift, and such things) thanks! - Vladislav Bublik
  • but when adding variables to the class, it produces the error 'map' produces' [T] ', not the expected contextual result type' [AddClass] ' - Vladislav Bublik
  • then the array should be declared as var and append( AddClass(name: "string") ) - Ilya Varfolomeev
  • corrected the post, look - Vladislav Bublik

You need during the creation of the AddClass object AddClass initialize all properties that are not optional or which are not initialized by default.

How you parse data into 2 different arrays and then form objects from these arrays is a bad style.

If initially you parse JSON you can do something like this (depending on the structure of your JSON):

 var result: [AddClass] = []() for item in jsonObject { guard let departDate = item["name"] as? String, let arrivalDate = item["release_date"] as? String else { return } let addClass = AddClass(name500: String, date500: String) } 

Or so:

 class AddClass: Codable { let name: String? let releaseDate: String? private enum CodingKeys: String, CodingKey { case name case releaseDate = "release_date" } } 

So we decode JSON into an AddClass object.

 let decoder = JSONDecoder() do { let result = try decoder.decode([AddClass].self, from: response.data!) } catch { print("error trying to convert data to JSON") print(error) } 

UPD: If it’s still difficult to do this, when you already have 2 arrays you simply create an object based on them:

 for (index, name500) in nameGame500.enumerated() { var game500 = dategame500[index] let addClass = AddClass(name500: name500, game500: game500) result.append(addClass) } 
  • It looks interesting, but I don’t know yet how to incorporate this into the project. Those. it is impossible to assign a regular array to a custom class? The way I use it - Vladislav Bublik
  • The last method helped, it works well, I wonder what this way can be bad?) - Vladislav Bublik
  • Understood the cant, when re-parsing, the data becomes two more due to adding to the array) - Vladislav Bublik