Understanding the Range of Values

Asked 2 years ago, Updated 2 years ago, 39 views

I didn't understand the reason why the titleList array values were taken in ★1, ★2, but I couldn't get the value in ★3, and how to deal with it.

import SwiftUI
import UIKit

structureNewsView:View {
    
    varnewsMap = NewsApiMap()
    @State variableList = [ ]
    @State var url = [ ]
    @State variable image=[ ]
    
    // Get and edit news
    func getData(data:News){
        self.titleList = [ ]
        url = [ ]
        image=[ ]
        for n —Int in (0...(data.articles.count-1){
            
            self.titleList.append (data.articles[n].title)
            self.url.append (data.articles[n].url)
            self.image.append (data.articles[n].urlToImage)
        }
        // ★1: TitleList[0] has a value
        print(titleList[0])
    }
    

    varbody:someView {
        
        VStack {
            VStack {
                Button(action: {newsMap.getNews(action:self.getData)}){
                    Text ("I want to take it when I see the screen")
                        .fontWeight (.bold).font (.title)
                        .foregroundColor (Color.black)
                }
                List{
                    // ★2: TitleList.count can be retrieved
                    Text("\(titleList.count)").foregroundColor(.blue)
                    // ★3: TitleList[0] cannot be retrieved
                Text("\(titleList[0])").foregroundColor(.blue)
                    
                }
            }
        }
    }
}

structureNewView_Previews:PreviewProvider{
    static var previews:someView {
        NewsView()
    }
}

I'm sorry I don't have enough information.The definitions of News and Article are as follows:

structure News:Codable {
    let status:String
    let totalResults—Int
    letarticles: Article
}


structureArticle:Codable {
    let title —String
    let url —String
    let urlToImage: String
}

Also, I was told that the Any type of array cannot be used in Text("()" so
The editData mezod contains the process of re-storing the article in the newsList below.

@StatevarnewsList: [(title:String, url:String, urlToImage:String)] = [ ]
// Get and edit news
    func getData(data:News){
        newsList = [ ]
        
        for vari: Int in (0...(data.articles.count-1)}
            self.newsList.append ((data.articles[i].title, data.articles[i].url, data.articles[i].urlToImage))
            i+=1
        }
    }

swift

2022-09-30 20:11

1 Answers

What does "I can't get a price" stand for?"Here, let's take the ""★3"" comment line as ""compilation error"" and write the answer."If you get an error, try to include an error message when you ask.

Also, regarding "how to respond", you cannot write certain definitions unless you know the definitions of NewsApiMap and News in the code you are questioning.

First of all, this is the most problematic part of your code.

@Statevar titleList=[]
    @State var url = [ ]
    @State variable image=[ ]

Since the declaration of these three properties does not specify the type, the type of the three properties is determined by [Any] (same as Array<Any>) and type inference.Each element has a Any type, and Swift has very limited operations on the Any type, so if you make a declaration like this, you will continue to be obsessed with strange errors.

You should try to avoid the Any type as much as possible in your code.

According to the News and Article definitions, titleList contains only elements of type String and should be clearly stated in the declaration.

@Statevar titleList: String = [ ]
    @State var url: [String] = [ ]
    @State variable image: [String] = [ ]

"This alone should not cause an error in the ""★3"" part (if it is as I assumed), but what do you think?"

If you use string interpolation literals for SwiftUI's Text, the \(...) expression type is limited; the String type is OK, but the Any type is not.This is completely different from print(...) that any data type was OK.

However, this is not limited to Swift, SwiftUI, and is generally true of programming, but it is not a good idea to expose individual elements and manage them as multiple separate arrays such as titleList, url, image.

You should declare it as an array of [Article] types as follows:

 structure NewsView:View {
    varnewsMap = NewsApiMap()
    @State vararticles: Article = [ ]
    
    // Get and edit news
    func getData(data:News){
        self.articles=data.articles
        // ★1: TitleList[0] has a value
        print(articles[0].title)
    }

    varbody:someView {
        VStack {
            VStack {
                Button(action: {newsMap.getNews(action:self.getData)}){
                    Text ("I want to take it when I see the screen")
                        .fontWeight (.bold).font (.title)
                        .foregroundColor (.black)
                }
                List{
                    // ★2: TitleList.count can be retrieved
                    Text("\(articles.count)").foregroundColor(.blue)
                    // ★3: TitleList[0] cannot be retrieved
                    Text("\(articles[0].title)").foregroundColor(.blue)
                }
            }
        }
    }
}

Incidentally, references such as articles[0] crash if articles are zero.I don't know how it will develop in the future, so I left it as it is, but you should be careful.

(About the additional code)
It has nothing to do with the direct question, but there is something wrong with the code in the additional part, so I will just point it out.

for vari:Int in (0...(data.articles.count-1)}
            //...
            i+=1
        }

Writing such a loop for all elements of an array is clearly irrational and funny.

    The
  • i value is automatically updated by for-in control; the i+=1 line is meaningless
  • (0...(data.articles.count-1) is normally used in Swift in the half-open range, such as 0..<data.articles.count
  • In this syntax, i can reliably be inferred as Int type, and it is usually better not to write a self-evident type

As a result, the for-in for that part should be written as follows (or is more common):

for in 0..<data.articles.count{
            self.newsList.append ((data.articles[i].title, data.articles[i].url, data.articles[i].urlToImage))
        }

(i in 0..<data.articles.count is better than i in data.articles.indices, map does not require the for statement itself, or article array does not require the conversion itself.)

I'm not saying you have to write like this, but you shouldn't leave useless lines in the code, and it's easier to read Swift's code if you get into the habit of writing it normally, and it's easier for other Swift programmers to read your code.


2022-09-30 20:11

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.