Related
I am having trouble when trying to compile my code as this error keeps appearing:
The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions.
Here is the section of the code where the error appears:
Any ideas on how I can get the code to compile and clear this error?
The solution would be to split your expressions into many expressions for example try replacing:
return Council(status: status ?? self.status,
council : council ?? self.council,
year: year ?? self.year,
councilRating: councilRating ?? self.councilRating,
annualChange: annualChange ?? self.annualChange,
councilTax: councilTax ?? self.councilTax)
With:
let s = status ?? self.status
let c = council ?? self.council
let y = year ?? self.year
let cr = councilRating ?? self.councilRating
let ac = annualChange ?? self.annualChange
let ct = councilTax ?? self.councilTax
return Council(status: s,
council : c,
year: y,
councilRating: cr,
annualChange: ac,
councilTax: ct)
I am looking for a way to detect years e.g. 2019. The requirements I think would be that the numbers are in a row, have four digits and are not adjacent to letters or special characters. So I'd like to get the method to return "2019" in each of the following cases:
"2019"
"in 2019
"Before 2019, all IOS apps were written in one of 2 ways"
But exclude it from:
"1234z20191234
There are a lot of ways to detect the numbers in a string as seen here such as
let newString = origString
.components(separatedBy:CharacterSet.decimalDigits.inverted)
.joined(separator: "")
But they don't pull out each series of numbers to test for length and adjacency.
Data detector can try to pull out a date but going from the possible date to the year that might have been in the starting text seems error prone e.g. working with something like:
“2018-08-31 04:00:00 +0000”, “America/Los_Angeles”, 18000.0
Can anyone suggest a reliable way to retrieve a numerical year from a string?
You might use regular expression, searching for four digits ([0-9]{4}) between word boundaries (\b), e.g.
let strings = [
"2019",
"in 2019",
"Before 2019, all IOS apps were written in one of 2 ways",
"1234z20191234"
]
for string in strings {
if let range = string.range(of: #"\b[0-9]{4}\b"#, options: .regularExpression) {
let year = String(string[range])
print(year)
} else {
print("No year found")
}
}
Producing:
2019
2019
2019
No year found
Note, the above uses Swift 5’s Extended String Delimiters, #" and "#. If doing this in earlier Swift versions, you’ll want to just escape the backslashes with yet another backslash:
if let range = string.range(of: "\\b[0-9]{4}\\b", options: .regularExpression) {
...
}
Clearly if you want to narrow the range of four digit numbers recognized as years, you’d have to tweak the regular expression or supplement it with some logic. But your question doesn’t identify what criteria you want to use to detect years.
You can do this with a regular expression. This code will find all years in a given string. You can set the check to confirm the number is within whatever range you wish to accept.
func findYears(in text: String) -> [String] {
let yearRE = try! NSRegularExpression(pattern: "(?:\\b)[0-9]{4}(?:\\b)")
var results = [String]()
yearRE.enumerateMatches(in: text, range: NSRange(text.startIndex..<text.endIndex, in: text)) { (result, flags, stop) in
if let result = result {
let match = String(text[Range(result.range(at: 0), in: text)!])
// Set whatever range you wish to accept
if let year = Int(match), year > 1600 && year < 2200 {
results.append(match)
}
}
}
return results
}
let yearStrings = [
"2019",
"in 2019 and 2020",
"Before 2019, all IOS apps were written in one of 2 ways",
"1234z20191234",
"2018-08-31 04:00:00 +0000",
]
for yearString in yearStrings {
print(findYears(in: yearString))
}
Output:
["2019"]
["2019", "2020"]
["2019"]
[]
["2018"]
let's say I have a string
var a = "#bb #cccc #ddddd\u{ef}"
and i am setting it to textview like this
let text = a.trimmingCharacters(in: .whitespacesAndNewlines)
let textRemoved = text?.replacingOccurrences(of: "\u{ef}", with: "", options: NSString.CompareOptions.literal, range:nil)
textView.text = textRemove
I am trying to remove the \u{ef} character here. But in textRemoved it is not happening. Please help me how to do it.
I am using Xcode 10. Looks like below Xcode version than 10 is working
fine. is it a bug of Xcode 10?
This is a late answer but I struggled to replace "\u{ef}" in string as well. During debugging when hovered over string it showed presence of \u{ef} but when print in description it only showed space.
let str = "\u{ef} Some Title"
print(str) //" Some Title"
I tried replacingOccurrences(of: "\u{ef}", with: "", options: NSString.CompareOptions.literal, range: nil).trimmingCharacters(in: .whitespaces) but it failed as well.
So I used below snippet and it worked like wonder.
let modifiedStr = str.replacingOccurrences(of: "\u{fffc}", with: "", options: NSString.CompareOptions.literal, range: nil).trimmingCharacters(in: .whitespaces)
print(modifiedStr) //"Some Title"
Hope this helps someone!!
i also faced same issue for "\u{e2}". i have searched a lot but unable to find any answer. then i have tried below code , which works for me.
var newString = ""
for char in strMainString.unicodeScalars{
if char.isASCII{
newString += String(char)
}
}
Hope that will also work for you too.
In Xcode 10 Playground, string replaces for \u{00EF} is working.
var a = "#bb #cccc #ddddd\u{ef}"
a = a.replacingOccurrences(of: "\u{00EF}", with: "")
I hope that will work for you.
I tried the following and it worked like a charm:
replacingOccurrences(of: "�", with: " ", options: NSString.CompareOptions.literal, range: nil)
e.g. 1
let text = "\u{ef}\u{ef}\u{ef}\u{ef}😇哦哦哦"
let text1 = text.replacingOccurrences(of: "\u{fffc}", with: "", options: String.CompareOptions.literal, range: nil)
let text2 = text.replacingOccurrences(of: "\u{ef}", with: "", options: String.CompareOptions.literal, range: nil).trimmingCharacters(in: .whitespaces)
runnable
<img src="https://i.stack.imgur.com/styVo.png"/>
e.g. 2
let strBefore = textDocumentProxy.documentContextBeforeInput
let strAfter = textDocumentProxy.documentContextAfterInput
var textInput = strBefore + strAfter
let textInput2 = textInput.replacingOccurrences(of: "\u{ef}", with: "", options: String.CompareOptions.literal, range: nil)
let textInput1 = textInput.replacingOccurrences(of: "\u{fffc}", with: "", options: String.CompareOptions.literal, range: nil).trimmingCharacters(in: .whitespaces)
runnable
<img src="https://i.stack.imgur.com/xGHtW.png"/>
Similar to question but with \u{e2} symbol (fix is the same):
\u{e2} is not a character rather subset of UTF8 plane which starts with 0xE2 byte.
So look here, E2 are general punctuation symbols.
There many symbols actually which started with \u{e2} but not limited to it and full char can be represented f.e. with e2 80 a8 bytes (line separator).
That explains why shown in Xcode \u{e2} can't be replaced with replacingOccurrences... function. In order to filter out correct symbol you have to know what exact symbol it is, f.e. by using the snippet below:
"\u{2028}&😲".forEach { (char) in
print(Data(char.utf8).map { String(format: "%02x", $0) }.joined(separator: " "))
}
it prints to console:
e2 80 a8
26
f0 9f 98 b2
which are byte representation for each symbol.
Next step is to filter your string, go here and search in 3d column your bytes and unicode code point value is what you need (first column) and write it in swift code like "\u{2028}\u{206A}..." (depending on your sorting).
The final function may look like:
func removingE2Symbols() -> String {
let specialChars = "\u{202A}\u{202C}"
return filter { !specialChars.contains($0) }
}
Try this
extension String {
var asciiString: String {
return String(self.unicodeScalars.filter{ $0.isASCII })
}
}
It,s working Please check again:
let a = "#bb #cccc #ddddd\u{ef}"
let text = a.trimmingCharacters(in: .whitespacesAndNewlines)
let textRemoved = text.replacingOccurrences(of: "\u{ef}", with: "", options: NSString.CompareOptions.literal, range:nil)
print(textRemoved)
After updating xCode i am getting this error into my code :
The compiler is unable to type-check this expression in reasonable
time; try breaking up the expression into distinct sub-expressions
The code :
//check popup in window frame
let spaceFromLeftSide = cutOutViewX.constant + cutOutViewWidth.constant/2 - (options.textWidth + padding*2)/2
if spaceFromLeftSide < 0{
if options.side == .bottom {
messageRightSpaceFromBottomDot.constant -= spaceFromLeftSide - padding
}
else if options.side == .top{
messageRightSpaceFromTopDot.constant += spaceFromLeftSide - padding
}
}
let spaceFromRightSide = cutOutViewX.constant + cutOutViewWidth.constant/2 + (options.textWidth + padding*2)/2
if spaceFromRightSide > targetView.frame.size.width{
if options.side == .bottom {
messageRightSpaceFromBottomDot.constant -= spaceFromRightSide - ( targetView.frame.size.width )
}
else if options.side == .top{
messageRightSpaceFromTopDot.constant += spaceFromRightSide - ( targetView.frame.size.width )
}
}
Error in line :
let spaceFromRightSide = cutOutViewX.constant + cutOutViewWidth.constant/2 + (options.textWidth + padding*2)/2
how to fix this ?
The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
This error appears when swift compiler finds the expression calculation lengthy. For more details check here
To resolve this, you just need to break your expression into smaller parts. Just like:
let cutOutxOrigin = 3 * cutOutViewX.constant / 2
let actualPadding = (options.textWidth + padding * 2) / 2
let spaceFromRightSide = cutOutxOrigin + actualPadding
I have faced similar issue with different scenario
I was trying to create array of string
let selectedData = [
(data?.nose?.stuffyNose) ?? "",
(data?.nose?.sinusProblems) ?? "",
(data?.nose?.hayFever) ?? "",
(data?.nose?.sneezingAttacks) ?? "",
(data?.nose?.excessiveMucusFormation) ?? ""
]
I have already addd Brackets () but still was not working.
To fix this I have added type [String]
let selectedData:[String] = [
(data?.nose?.stuffyNose) ?? "",
(data?.nose?.sinusProblems) ?? "",
(data?.nose?.hayFever) ?? "",
(data?.nose?.sneezingAttacks) ?? "",
(data?.nose?.excessiveMucusFormation) ?? ""
]
Hope it is helpful to someone facing same issue
Just try to break up the expression to several simpler subexpression. E.g.:
let halfOfViewWidth = cutOutViewWidth.constant / 2
let textWidthAndPadding = options.textWidth + (padding * 2)
let spaceFromRightSide = cutOutViewX.constant + halfOfViewWidth + (textWidthAndPadding / 2)
EDIT
I noticed that I was able to fix this type of error also by providing explicit type conversions (e.g., instead of relying on the compiler to infer that by multiplying a CGFloat with an Int it should result in CGFloat, I have explicitly converted the Int to CGFloat). Seems that the problem lies indeed in types and automatic type inference and checking. While breaking up the the complex expression to smaller parts can be very useful to readability, you can solve the problem by being explicit about the types (the error message basically says that the compiler is unable do the type check - thus you can help it by providing explicit types where-ever possible).
I had this error when I accidentally mixed in an optional in an expression. After force unwrapping the error went away.
let a : String = "A"
let b : String = "B"
let c = letterDictionary["C"]
let imageName : String = a + b + c //error
let imageName : String = a + b + c! //no error
So I have this kind of expression:
return (50 + textHeight) + (dateTextHeight + 16) + (5 + 8) + (16 + 20)
I knew I had to breakdown or make this expression shorter to get rid of the error. Like perhaps:
return (50 + textHeight) + (dateTextHeight + 16) + 49
Although true enough it helped the compiler to do its job, the main cause of the error is the optional Int textHeight. I think no matter how long your expression, it should be compile-able.
I see this issue quite regularly when working with SwiftUI, and it's always been the result of a syntax error. I'm currently using Xcode 11.4.1, and it was true for earlier versions supporting SwiftUI.
For example, I just burned 50 mins with this error because I'd changed the name of a function parameter in another file. The compiler reported this error in a SwiftUI file that was completely untouched, except it invoked the function without the changed parameter name. Rather than explicitly pointing out the parameter name mismatch is baulked with this error.
This error occurs when compiler is confused. I ran into it doing a lengthy calculation that mixes various number types
I was able to remedy this by casting various sub-calculations into CGFloat. I did not need to "break up" expressions as suggested by some answers.
From: (some float expression) * someDouble / someInt
To: (some float expression) * CGFloat(someDouble / someInt)
I had the same problem here:
#State var sliderpos : CGFloat = (UIScreen.main.bounds.width-32)*(50/100)+(16-20) //causes error
But this works :
#State var sliderpos : CGFloat = (UIScreen.main.bounds.width-32)*(50/100)-4
This happened to me. I was passing two Float to a SwiftUI struct and subtracting one from the other inside, but by mistake I defined the Float inside the as Dates (damn you, copy-paste!).
It was basically this.
struct Something: View {
var minValue: Date
var maxValue: Date
var body: some View {
let valueDifference = maxValue - minValue
}
}
I was calling it like this:
let minValue: Float = 0
let maxValue: Float = 1
Something(minValue: minValue, maxValue: maxValue)
Note I'm actually passing two Float, but the struct is accepting them even though they're defined as Date.
As soon as I changed the Date types to Float the problem was gone.
I had two instances of this so far:
changed a view that needed a binding as an argument to one using an environmental object but still had a call to MyView($binding) instead of MyView(). In a completely different view, this error appeared. I commented out the most complex code (a switch statement with seven different views) and the compiler found the problem.
– tried something, didn't like it, got into a muddle, caused the error. Discarded all changes rather than trying to unpick the problem; error persisted even though it ran and built ok. Cleaned build folder, error went away.Sent computer to sleep, error came back. Cleaned build folder again, error went away (& project built). Compiler is clearly confused - if this persists, will send project to Apple.
Further observation tells me that it builds and runs fine, the compiler is happy afterwards, thinks about it, and THEN throws the error, which has no effect on the project's ability to run.
I think I got him. I added several more views to the project (for now, without adding them to any view hierarchies, just sitting there quietly), and the error became permanent.
So I looked at the file where the error is marked again, and decided I can do without the group. Since then, I haven't seen the error again.
This is indeed a memory problem. It happened to me, when I only 350 mb of free memory on my 16GB machine. Using f.e. CleanMyMac -> Free up memory resolved this problem.
By simply doing that :
let array = [Int]()
let dic = [Int : Double]()
let tuple = array.map { c -> (a: Int, b: Double) in return (a: c, b: dic[c]!) }.sorted(by: { (first, second) -> Bool in return first.b == second.b ? first.a < second.a : first.b > second.b }).first!
Xcode 11.6 takes 10 sec of Cpu with 4 processes running at 100% consuming a lot of Watts on my MacPro 2019 and i got the error : (The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions)
Even with only a map and a sort combined !
If i split in 2 :
let temporaryTupleArrayToAvoidTheCompilerBug = array.map { c -> (a: Int, b: Double) in return (a: c, b: dic[c]!) }
let tuple = temporaryTupleArrayToAvoidTheCompilerBug.sorted(by: { (first, second) -> Bool in return first.b == second.b ? first.a < second.a : first.b > second.b }).first!
It works.
The error message is here to hide a bug, the compiler can split the instruction and check the methods syntax separately.
I had an expression with several uses of an optional variable, with fallback values, like this:
if ((self.scrollView?.contentSize.width ?? 0.0) > 0.0) && ((self.scrollView?.contentSize.height ?? 0.0) > 0.0) && ((self.scrollView?.frame.size.height ?? 0.0) > 0.0) {
The error went away when I made a non-optional copy of the variable:
guard let scrollView = self.scrollView else { return }
if (scrollView.contentSize.width > 0.0) && (scrollView.contentSize.height > 0.0) && (scrollView.frame.size.height > 0.0) {
Depending on what you want to do when the optional variable is nil, this one-line version could also be useful:
if let scrollView = self.scrollView, (scrollView.contentSize.width > 0.0), (scrollView.contentSize.height > 0.0), (scrollView.frame.size.height > 0.0) {
I ran into this issue on Firebase when updating data for individual keys as per documentation.
// Update Cards
self.database.collection(FirebaseDatabaseKeys.cards).document(docId).setData([
"id": docId,
"cardNumber": card.cardNumber ?? "",
"isFavorite": card.isFavorite,
"numberOfCards": card.numberOfCards,
"playerName": card.playerName?.uppercased() ?? "",
"year": card.year ?? "",
"sport": card.sport ?? "",
"brand": card.brand ?? "",
"set": card.set ?? "",
"parallel": card.parallel ?? "",
"serial": card.serial ?? "",
"owner": uid ?? "",
CardSide.frontCard.imageKey: "",
CardSide.backCard.imageKey: ""
]) { err in
if let error = err {
print(error.localizedDescription)
}
}
I resolve it creating the dictionary prior to calling setData
// Create Data
let cardData: [String: Any] = [
"id": docId,
"cardNumber": card.cardNumber ?? "",
"isFavorite": card.isFavorite,
"numberOfCards": card.numberOfCards,
"playerName": card.playerName?.uppercased() ?? "",
"year": card.year ?? "",
"sport": card.sport ?? "",
"brand": card.brand ?? "",
"set": card.set ?? "",
"parallel": card.parallel ?? "",
"serial": card.serial ?? "",
"owner": uid ?? "",
CardSide.frontCard.imageKey: "",
CardSide.backCard.imageKey: ""
]
// Update Cards
self.database.collection(FirebaseDatabaseKeys.cards).document(docId).setData(cardData) { err in
if let error = err {
print(error.localizedDescription)
}
}
One possible case is that i splice string with enum.
eg:
enum Fruit: String {
case apple
}
let fruit = Fruit.apple
then i splice occur the error
let url = "/api/" + fruit
fruit is a Enum field rather than a String. I fix with
let url = "/api/" + fruit.rawValue
I'm trying to delete numbers at the end of the string but I couldn't do that. How can I do it?
Example:
swift 23
ios 36
iphone 25
swift
ios
iphone
but also i want to show numbers at the begin.
example:
25 january 2018 my question
11 september 2001
UPDATE
That's my code:
func parseHTML(html: String) -> Void {
if let doc = try? HTML(html: html, encoding: .utf8) {
var showString = String()
for show in doc.css("ul[class^='topic'] li a"){
showString = show.text!.trimmingCharacters(in: CharacterSet.decimalDigits) //it's remove whole numbers
goster.append(showString)
}
UPDATE
The question changed so this answer probably won't work for you now.
A quick approach if there is always going to be a space or more in between is:
var str = "swift 23"
let newString = str.split(separator: " ").first
You can use String.replacingOccurences(of:,with:,options:) with a regex to only match digits at the end of your Strings.
let stringsWithNumbers = ["swift 23", "ios 36", "iphone 25","25 january 2018 my question","11 september 2001"]
let newStrings = stringsWithNumbers.map({$0.replacingOccurrences(of: "\\d+$", with: "", options: .regularExpression)})
print(newStrings)
Output:
["swift ", "ios ", "iphone ", "25 january 2018 my question", "11
september "]
If you also want to remove the whitespaces at the end of the Strings, just change the regex to "\\s*\\d+$".