Compare a part of text to a String - ios

I'm trying to get the range of a text, I did this:
let telRange = Range(start: tfTelephone.text!.startIndex, end: tfTelephone.text!.endIndex.advancedBy(2))
After this I'm trying to compare:
if (telRange == "08")
But I get an error:
Binary operator '==' cannot be applied to operands of type
'Range' (aka 'Range') and 'String'

Firstly, don't force unwrap, use an if-let instead. Secondly, you can't compare a Range and a String, most likely you want to compare the substring for that range. And thirdly, you can't advance forward from the endIndex.
let telRange: String
if let text = tfTelephone.text {
telRange = text[text.startIndex...text.endIndex.advancedBy(-2)]
} else {
telRange = ""
}
Something like above should work, you can tweak the indexes and the advanceBy arguments to match your expectations.

You should be doing something like this instead:
if (tfTelephone.text![telRange] == "08") {
// ...
}
However, before that will work you have to fix this:
let telRange = Range(
start: tfTelephone.text!.startIndex,
end: tfTelephone.text!.endIndex.advancedBy(2) // <- This will fail. Use negative
) // number, and make sure to stay
// within the length of the input
// string still.

Try something like this:
let yourString = tfTelephone.text
let telRange = Range(start: yourString!.startIndex, end: yourString!.endIndex.advancedBy(-2)) //It's important to use only negative numbers!
let stringToCompare = yourString!.substringWithRange(telRange)
Now you can compare the two strings
if (stringToCompare == "08")

Related

How to split uncode string into characters

I have strings like
"\U0aac\U0ab9\U0ac1\U0ab5\U0a9a\U0aa8",
"\U0a97\U0ac1\U0ab8\U0acd\U0ab8\U0acb",
"\U0aa6\U0abe\U0ab5\U0acb",
"\U0a96\U0a82\U0aa1"
But I want to split this strings by unicode character
I dont know hot to do. I know components seprated by function but it's no use here.
\nAny help would be apperiaciated
If the strings you're getting really contain \U characters, you need to parse them manually and extract the unicode scalar values. Something like this:
let strings = [
"\\U0aac\\U0ab9\\U0ac1\\U0ab5\\U0a9a\\U0aa8",
"\\U0a97\\U0ac1\\U0ab8\\U0acd\\U0ab8\\U0acb",
"\\U0aa6\\U0abe\\U0ab5\\U0acb",
"\\U0a96\\U0a82\\U0aa1"
]
for str in strings {
let chars = str.components(separatedBy: "\\U")
var string = ""
for ch in chars {
if let val = Int(ch, radix: 16), let uni = Unicode.Scalar(val) {
string.unicodeScalars.append(uni)
}
}
print(string)
}
You can map your array, split its elements at non hexa digit values, compact map them into UInt32 values, initializate unicode scalars with them and map the resulting elements of your array into a UnicodeScalarView and init a new string with it:
let arr = [
#"\U0aac\U0ab9\U0ac1\U0ab5\U0a9a\U0aa8"#,
#"\U0a97\U0ac1\U0ab8\U0acd\U0ab8\U0acb"#,
#"\U0aa6\U0abe\U0ab5\U0acb"#,
#"\U0a96\U0a82\U0aa1"#]
let strings = arr.map {
$0.split { !$0.isHexDigit }
.compactMap { UInt32($0, radix: 16) }
.compactMap(Unicode.Scalar.init)
}.map { String(String.UnicodeScalarView($0)) }
print(strings)
This will print
["બહુવચન", "ગુસ્સો", "દાવો", "ખંડ"]
So, the string that comes back already has the "\" because in order to use components you'd need to have an additional escaping "\" so that you'd be able to do:
var listofCodes = ["\\U0aac\\U0ab9\\U0ac1\\U0ab5\\U0a9a\\U0aa8", "\\U0aac\\U0ab9\\U0ac1\\U0ab5\\U0a9a\\U0aa8"]
var unicodeArray :[String] = []
listofCodes.forEach { string in
unicodeArray
.append(contentsOf: string.components(separatedBy: "\\"))
unicodeArray.removeAll(where: {value in value == ""})
}
print(unicodeArray)
I will revise this answer once you specify how you are obtaining these strings, as is I get a non-valid string error from the start.

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

I am new in Ios programming and the below expressing is giving an error:
let combine = date.enumerated().map {index, date in
return (date,self.arrFriendId[index],self.arrFriendName[index],self.arrFriendImage[index],self.arrMsgType[index],self.arrMessage[index], self.arrLastMsgTime[index], self.arrNotifyStatus[index])}
please help me to solve this.
thanks in advance
This error generally occurs when a single expression is doing a lot of things. So compiler tells you to break it to sub-expressions.
Assuming you want the output combine of type Array<Any>, You can do it like this:
let combine = date.enumerated().map { index, date -> Any in
let id = self.arrFriendId[index]
let name = self.arrFriendName[index]
let image = self.arrFriendImage[index]
let messageType = self.arrMsgType[index]
let message = self.arrMessage[index]
let messageTime = self.arrLastMsgTime[index]
let status = self.arrNotifyStatus[index]
return (date, id, name, image, messageType, message, messageTime, status)
}

How to get range of specific substring even if a duplicate

I want to detect the words that begin with a #, and return their specific ranges. Initially I tried using the following code:
for word in words {
if word.hasPrefix("#") {
let matchRange = theSentence.range(of: word)
//Do stuff with this word
}
}
This works fine, except if you have a duplicate hashtag it will return the range of the first occurrence of the hashtag. This is because of the nature of the range(_:) function.
Say I have the following string:
"The range of #hashtag should be different to this #hashtag"
This will return (13, 8) for both hashtags, when really it should return (13, 8) as well as (50, 8). How can this be fixed? Please note that emojis should be able to be detected in the hashtag too.
EDIT
If you want to know how to do this with emojis to, go here
Create regex for that and use it with the NSRegularExpression and find the matches range.
var str = "The range of #hashtag should be different to this #hashtag"
let regex = try NSRegularExpression(pattern: "(#[A-Za-z0-9]*)", options: [])
let matches = regex.matchesInString(str, options:[], range:NSMakeRange(0, str.characters.count))
for match in matches {
print("match = \(match.range)")
}
Why don't you separate your word in chunks where each chunk starts with #. Then you can know how many times your word with # appears in sentence.
Edit: I think that regex answer is the best way for this but this is an other approach for same solution.
var hastagWords = [""]
for word in words {
if word.hasPrefix("#") {
// Collect all words which begin with # in an array
hastagWords.append(word)
}
}
// Create a copy of original word since we will change it
var mutatedWord = word.copy() as! String
for hashtagWord in hastagWords {
let range = mutatedWord.range(of: hashtagWord)
if let aRange = range {
// If range is OK then remove the word from original word and go to an other range
mutatedWord = mutatedWord.replacingCharacters(in: aRange, with: "")
}
}

Return range with first and last character in string

I have a string: "Hey #username that's funny". For a given string, how can I search the string to return all ranges of string with first character # and last character to get the username?
I suppose I can get all indexes of # and for each, get the substringToIndex of the next space character, but wondering if there's an easier way.
If your username can contain only letters and numbers, you can use regular expression for that:
let s = "Hey #username123 that's funny"
if let r = s.rangeOfString("#\\w+", options: NSStringCompareOptions.RegularExpressionSearch) {
let name = s.substringWithRange(r) // #username123"
}
#Vladimir's answer is correct, but if you're trying to find multiple occurrences of "username", this should also work:
let s = "Hey #username123 that's funny"
let ranges: [NSRange]
do {
// Create the regular expression.
let regex = try NSRegularExpression(pattern: "#\\w+", options: [])
// Use the regular expression to get an array of NSTextCheckingResult.
// Use map to extract the range from each result.
ranges = regex.matchesInString(s, options: [], range: NSMakeRange(0, s.characters.count)).map {$0.range}
}
catch {
// There was a problem creating the regular expression
ranges = []
}
for range in ranges {
print((s as NSString).substringWithRange(range))
}

Swift, get variable name from a string

I have a question. I know that this can be done in Ruby, not sure about Swift, but never did anything similar.
What I'm working on is a program that works similar to this: if the user writes in a TextView "a + b", my code should elaborate the value of the sum between the variable "a" and "b".
What I mean is, how can I get variable names from a string? Is it possible at all?
If it's not, I'd use a switch (variable names are limited), but I'd need to "connect" a variable to the one written by the user. In the example, if the user writes "a + b", my sum function is something like "sum(par1,par2)", so, how can I make variable "par1" point to "a" and "par2" point to "b"? I can do that with pointers right? Is there any other way?
I'm not sure I've been clear, but it's quite hard to explain
Check this out. You can do with NSExpression and KVC.
class myclass:NSObject {
var a = 10;
var b = 20;
override init() {
super.init();
}
}
var obj = myclass();
// Expression from user
var expr:NSString = "a+b" ;
//Operators..
let opSet = NSMutableCharacterSet()
opSet.addCharactersInString("+-*/");
let components:NSArray = expr.componentsSeparatedByCharactersInSet(opSet)
let uniqueChars:NSSet = NSSet(array: components)
for variable in uniqueChars
{
expr = expr.stringByReplacingOccurrencesOfString ( variable as String,
withString : NSString(format: "%d", obj.valueForKey(variable as String) as Int),
options : NSStringCompareOptions.LiteralSearch,
range : NSMakeRange(0,expr.length) );
}
var result: AnyObject = NSExpression(format: expr).expressionValueWithObject(nil, context: nil)
print (result);

Resources