Array cleaning in Swift - ios

I have an array in Swift:
["\"100003866283798-2\"", "\"100001986741004-2\"",
"\"100003455181526-2\"", "\"100002261472542-2\"",
"\"100003866283798-3\"", "\"100003866283798-0\"",
"\"100001986741004-3\"", "\"100001986741004-0\"",
"\"100003455181526-3\"", "\"100003455181526-0\"",
"\"100002261472542-3\"", "\"100002261472542-0\""]
and I only want the numbers, not the quotes and the -2.
I can't figure out to do this, because when I type
let cleanStr = numberArray.stringByReplacingOccurrencesOfString("\"", withString: "", options: nil, range: nil)
it gives the error:
Value of type '[String]' has no member
'stringByReplacingOccurrencesOfString'
I know it's very confusing with all the quotes etc but I want these numbers without their quotes etc, anyone a solution?

You can do it like this:
let newArray = array.map { (string: String) -> String in
let woFirst = string.characters.dropFirst()
let tilDash = woFirst.prefixUpTo(
woFirst.indexOf("-") ?? woFirst.endIndex)
return String(tilDash)
}
(Weirdly it doesn't compile without the type annotation). Or if you feel fancy:
let newArray = array
.map{ {$0.prefixUpTo($0.indexOf("-") ?? $0.endIndex)}($0.characters.dropFirst()) }
.map(String.init)
(XCode 7 beta 6)

stringByReplacingOccurrencesOfString
works only with NSString not Array. Then you must iterate your array remove excess char.

Related

swift - get value from string using regular expression

I want to extract a value from a string in swift 4.
I tried to use regular expression but it didn't work all i want is to extract the PK value from this query:
"INSERT INTO table(PK,anotherValue) VALUES ('38061','1233')"
I want the result here to be: 38061
the regex i tried:
var results = [String]()
do{
let regex = try NSRegularExpression(pattern:" VALUES ('(.*?)'", options: [])
regex.enumerateMatches(in: query, options: [], range: NSMakeRange(0, query.utf16.count)) { result, flags, stop in
if let r = result?.range(at: 1), let range = Range(r, in: query) {
results.append(String(query[range]))
}
}
} catch {
print( error)
}
print(results)
i got below error :
Error Domain=NSCocoaErrorDomain Code=2048 "The value “ VALUES
('(.?)'” is invalid." UserInfo={NSInvalidValue= VALUES ('(.?)'
The parentheses are special characters for capturing groups.
To treat a parenthesis as literal character you have to escape it:
pattern:" VALUES \\('(.*?)'"
Please look at:
https://regex101.com/r/lyzoex/1

Swift String operation not working

I am trying to read the string from a Label and remove the last character form it.
This is how I am trying:
#IBAction func del(sender: UIButton) {
let str = telephone.text!;
let newstr = str.remove(at: str.index(before: str.endIndex))
telephone.text = newstr;
}
When I run, I get an error:
"String" does not have a member named "remove"
Can someone help me figure out the problem?
Just started learning swift :(
remove(at:) mutates the receiver which must therefore be a variable
string:
var str = telephone.text!
str.remove(at: str.index(before: str.endIndex))
telephone.text = str
Alternatively use substring(to:), which returns the new string
instead of modifying the receiver:
let str = telephone.text!
let newstr = str.substring(to: str.index(before: str.endIndex))
telephone.text = newstr
remove is defined as follows:
public mutating func remove(at i: String.Index) -> Character
See the mutating modifier? That means it mutates the instance on which the method is called. In your case, the instance is str, a constant. Since constants cannot be mutated, the code does not compile.
And since remove returns the removed character,
let newstr = str.remove(at: str.index(before: str.endIndex))
here newstr will not be storing the string with the last character removed.
You should rewrite the method like this:
telephone.text!.remove(at: telephone.text!.index(before: telephone.text!.endIndex))
You can use:
let idx = str.index(before: str.endIndex) // compute the index
let s = str.substring(to: idx) // get the substring

How to get value from point(a b) swift

I have this kind of string: "POINT(101.650577657408 3.1653186153213)".
Anyone know how can I get the first and second value of POINT from this String?
You can easily spit the string using componentsSeparatedByString function.
let myStr = "POINT(101.650577657408 3.1653186153213)"
let characterSet = NSCharacterSet(charactersInString: "( )")
var splitString = myStr.componentsSeparatedByCharactersInSet(characterSet)
print(splitString[0])
print(splitString[1])
print(splitString[2])
The above only works if you have the complete one String.
Although the NSCharacterSet solution is correct but here is another solution using the most powerful regex.
var error: NSError?
// Initialise the regex for a float value
let regex: NSRegularExpression = NSRegularExpression(pattern: "(\\d*\\.\\d*)", options: NSRegularExpressionOptions.CaseInsensitive, error: &error)!
// Matches array contains all the match found for float in given string
let matches: NSArray = regex.matchesInString(str as String, options: NSMatchingOptions.ReportProgress, range: NSMakeRange(0, str.length))
// You can easily get all values by enumeration
for match in matches {
println(str.substringWithRange(match.range))
}
The benefit of this solution is it will scan all the float values and will also work in case of pattern got changed.
Try this, this will work for your string
let myStr = "POINT(101.650577657408 3.1653186153213)"
let strWithout_POINT_openingBrace = myStr.stringByReplacingOccurrencesOfString("POINT(", withString: "")//"101.650577657408 3.1653186153213)"
let strWithout_closingBrace = strWithout_POINT_openingBrace.stringByReplacingOccurrencesOfString(")", withString: "")//"101.650577657408 3.1653186153213"
//now you have only space between two values
//so split string by space
let arrStringValues = strWithout_closingBrace.componentsSeparatedByString(" ");//["101.650577657408","3.1653186153213"]
print(arrStringValues[0]);//first value "101.650577657408"
print(arrStringValues[1]);//second value "3.1653186153213"

Is it possible to get a rangeOfString from a group of items in an array?

What i've tried was using a for-in loop, however that just cycles to the last value and gives me the rangeOfString for that value. It would be a lot to write the rangeOfString for all the values i want but if needed I don't mind. I just wanted to know if it was possible to use an array instead.
while true {
let attempts = ["hello","goodbye"]
for attempt in attempts{
tru = attempt
let range = text.rangeOfString("hello", options: [], range: searchRange)
You can use map:
let text: NSString = "hello goodbye"
let attempts = ["hello", "goodbye"]
let ranges = attempts.map { text.rangeOfString($0, options: NSStringCompareOptions(rawValue: 0)) }

Swift filter array of strings

I've had troubles filtering array of keywords (strings) in swift ,My code:
self.filteredKeywords=filter(keywords.allValues, {(keyword:NSString) ->
Bool in
let words=keyword as? NSString
return words?.containsString(searchText)
})
As AnyObject can't be subtype of NSString, I'm stuck with this!
[Updated for Swift 2.0]
As NSString is toll-free bridged to Swift String, just avoid the coercions with:
3> ["abc", "bcd", "xyz"].filter() { nil != $0.rangeOfString("bc") }
$R1: [String] = 2 values {
[0] = "abc"
[1] = "bcd"
}
But, if you think allValues aren't strings:
(keywords.allValues as? [String]).filter() { nil != $0.rangeOfString("bc") }
which returns an optional array.
Your filter is over [AnyObject], but your closure takes NSString. These need to match. Also, your result needs to be a Bool, not a Bool?. You can address these simply like this:
self.filteredKeywords = filter(keywords.allValues, {
let keyword = $0 as? NSString
return keyword?.containsString(searchText) ?? false
})
This accepts AnyObject and then tries to coerce it down to NSString. It then nil-coalleces (??) the result to make sure it always is a Bool.
I'd recommend, though, treating keywords as a [String:String] rather than an NSDictionary. That would get rid of all the complications of AnyObject. Then you can just do this:
self.filteredKeywords = keywords.values.filter { $0.rangeOfString(searchText) != nil }
Whenever possible, convert Foundation collections into Swift collections as soon as you can and store those. If you have incoming Foundation objects, you can generally convert them easily with techniques like:
let dict = nsdict as? [String:String] ?? [:]
Or you can do the following to convert them such that they'll crash in debug (but silently "work" in release):
func failWith<T>(msg: String, value: T) -> T {
assertionFailure(msg)
return value
}
let dict = nsdict as? [String:String] ?? failWith("Couldn't convert \(d)", [:])
Swift 4.2 provides a new way to do this:
var theBigLebowski = ["The Dude", "Angry Walter", "Maude Lebowski", "Donny Kerabatsos", "The Big Lebowski", "Little Larry Sellers"]
// after removeAll -> ["The Dude", "Angry Walter", "Donny Kerabatsos", "Little Larry Sellers"]
theBigLebowski.removeAll{ $0.contains("Lebowski")}
print(theBigLebowski)
There is both a problem with GoZoner's answer for certain data types and also a slightly better way to do this. The following examples can show this:
let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"]
let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil }
print("filteredAnimals:", filteredAnimals)
filteredAnimals: [Dog, Cat, Otter, Deer, Rabbit]
Likely not the set you expected!
However this works fine this way if we don't type animalArray as an NSMutableArray:
let animalArray = ["Dog","Cat","Otter","Deer","Rabbit"]
let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil }
print("filteredAnimals:", filteredAnimals)
filteredAnimals: [Otter, Deer]
However I'd recommend using $0.contains() instead of $0.rangeOfString() != nil because it functions in both circumstances and slightly enhances the readability of the code:
let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"]
let filteredAnimals = animalArray.filter { $0.contains("er") }
print("filteredAnimals:", filteredAnimals)
filteredAnimals: [Otter, Deer]

Resources