I use swift and what i want to do is to check this:
if string.characterAtIndex(i) == "a"
But i get error. How to convert this "a" so that can be same type with characters i loop.
Thanks.
You need to convert you UniChar - characterAtIndex(i) to a Character, so you can compare them.
Solution:
let ithChar:Character = Character(UnicodeScalar(string.characterAtIndex(i)))
if ithCahr == "a"
{
//do some stuff
}
Hope it helps!
Here is another way you could do it:
if string.characterAtIndex(i) == "a".characterAtIndex(0)
In better explanatory way, this can be one of the ways to perform what you intend to do.
var str = "Hello, playground"
var newString = str as NSString
var num:Int = countElements(str)
for var i = 0; i < num; i++
{
if ( Array(str)[i] == "p") {
println(Array(str)[i]) // will show the output
println("success");
break;
}
}
Related
I have this string "01:07:30" and I would like to remove the zero in "01" and keep everything else the same. My final string should look like this
"1:07:30"
Is there a way to do so in Swift? Thank you so much!
Try the following. This will create a string, check to see if the first character is 0 if it is remove it. Otherwise do nothing.
var myString = "01:07:30"
if myString.first == "0" {
myString.remove(at: myString.startIndex)
}
print(myString) // 1:07:30
The final result is the string will now be 1:07:30 instead of 01:07:30.
If I'm best understanding your question, you want to replace the occurrences of "01" with "1" in your string, so you can use regex or the string functionality it self
simply:
let searchText = "01"
let replaceWithValue = "1"
let string = "01:07:08:00:01:01"
let newString = string.replacingOccurrences(of: searchText, with: replaceWithValue) // "1:07:08:00:1:1"
If you want to replace the fist occurrence only, simply follow this answer:
https://stackoverflow.com/a/33822186/3911553
If you just want to deal with string here is one of many solution:
var myString = "01:07:30"
let list = myString.components(separatedBy: ":")
var finalString = ""
for var obj in list{
if obj.first == "0" {
obj.removeFirst()
}
finalString += finalString.count == 0 ? "\(obj)" : ":\(obj)"
}
print(finalString)
I have a string called source. This string contains tags, marked with number signs (#) on left and right side.
What is the most efficient way to get tag names from the source string.
Source string:
let source = "Here is tag 1: ##TAG_1##, tag 2: ##TAG_2##."
Expected result:
["TAG_1", "TAG_2"]
Not a very short solution, but here you go:
let tags = source.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: " ,."))
.filter { (str) -> Bool in
return str.hasSuffix("##") && str.hasPrefix("##")
}
.map { (str) -> String in
return str.stringByReplacingOccurrencesOfString("##", withString: "")
}
Split the string at all occurences of ##:
let components = source.components(separatedBy: "##")
// Result: ["Here is tag 1: ", "TAG_1", ", tag 2: ", "TAG_2", "."]
Check that there's an odd number of components, otherwise there's an odd amount of ##s:
guard components.count % 2 == 1 else { fatalError("Unbalanced delimiters") }
Get every second element:
components.enumerated().filter{ $0.offset % 2 == 1 }.map{ $0.element }
In a single function:
import Foundation
func getTags(source: String, delimiter: String = "##") -> [String] {
let components = source.components(separatedBy: delimiter)
guard components.count % 2 == 1 else { fatalError("Unbalanced delimiters") }
return components.enumerated().filter{ $0.offset % 2 == 1 }.map{ $0.element }
}
getTags(source: "Here is tag 1: ##TAG_1##, tag 2: ##TAG_2##.") // ["TAG_1", "TAG_2"]
You can read this post and adapt the answer for your needs: Swift: Split a String into an array
If not you can also create your own method, remember a string is an array of characters, so you can use a loop to iterate through and check for a '#'
let strLength = source.characters.count;
var strEmpty = "";
for( var i=0; i < strLength; i++ )
{
if( source[ i ] == '#' )
{
var j=(i+2);
for( j; source[ (i+j) ] != '#'; j++ )
strEmpty += source[ (i+j) ]; // concatenate the characters to another variable using the += operator
i = j+2;
// do what you need to with the tag
}
}
I am more of a C++ programmer than a Swift programmer, so this is how I would approach it if I didn't want to use standard methods. There may be a better way of doing it, but I don't have any Swift knowledge.
Keep in mind if this does not compile then you may have to adapt the code slightly as I do not have a development environment I can test this in before posting.
I have a Swift based iOS app and one of the features allows you to comment on a post. Anyway, users can add "#mentions" in their posts to tag other people. However I want to stop the user from adding a username with a capital letter.
Is there anyway I can convert a string, so that the #usernames are all in lowercase?
For example:
I really enjoy sightseeing with #uSerABC (not allowed)
I really enjoy sightseeing with #userabc (allowed)
I know there is a property for the string in swift called .lowercaseString - but the problem with that, is that it makes the entire string lowercase and thats not what I want. I only want the #username to be in lower case.
Is there any way around this with having to use the .lowercase property.
Thanks for your time, Dan.
This comes from a code I use to detect hashtags, I've modified to detect mentions:
func detectMentionsInText(text: String) -> [NSRange]? {
let mentionsDetector = try? NSRegularExpression(pattern: "#(\\w+)", options: NSRegularExpressionOptions.CaseInsensitive)
let results = mentionsDetector?.matchesInString(text, options: NSMatchingOptions.WithoutAnchoringBounds, range: NSMakeRange(0, text.utf16.count)).map { $0 }
return results?.map{$0.rangeAtIndex(0)}
}
It detects all the mentions in a string by using a regex and returns an NSRange array, by using a range you have the beginning and the end of the "mention" and you can easily replace them with a lower case version.
Split the string into two using the following command -
let arr = myString.componentsSeparatedByString("#")
//Convert arr[1] to lower case
//Append to arr[0]
//Enjoy
Thanks to everyone for their help. In the end I couldn't get any of the solutions to work and after a lot of testing, I came up with this solution:
func correctStringWithUsernames(inputString: String, completion: (correctString: String) -> Void) {
// Create the final string and get all
// the seperate strings from the data.
var finalString: String!
var commentSegments: NSArray!
commentSegments = inputString.componentsSeparatedByString(" ")
if (commentSegments.count > 0) {
for (var loop = 0; loop < commentSegments.count; loop++) {
// Check the username to ensure that there
// are no capital letters in the string.
let currentString = commentSegments[loop] as! String
let capitalLetterRegEx = ".*[A-Z]+.*"
let textData = NSPredicate(format:"SELF MATCHES %#", capitalLetterRegEx)
let capitalResult = textData.evaluateWithObject(currentString)
// Check if the current loop string
// is a #user mention string or not.
if (currentString.containsString("#")) {
// If we are in the first loop then set the
// string otherwise concatenate the string.
if (loop == 0) {
if (capitalResult == true) {
// The username contains capital letters
// so change it to a lower case version.
finalString = currentString.lowercaseString
}
else {
// The username does not contain capital letters.
finalString = currentString
}
}
else {
if (capitalResult == true) {
// The username contains capital letters
// so change it to a lower case version.
finalString = "\(finalString) \(currentString.lowercaseString)"
}
else {
// The username does not contain capital letters.
finalString = "\(finalString) \(currentString)"
}
}
}
else {
// The current string is NOT a #user mention
// so simply set or concatenate the finalString.
if (loop == 0) {
finalString = currentString
}
else {
finalString = "\(finalString) \(currentString)"
}
}
}
}
else {
// No issues pass back the string.
finalString = inputString
}
// Pass back the correct username string.
completion(correctString: finalString)
}
Its certainly not the most elegant or efficient solution around but it does work. If there are any ways of improving it, please leave a comment.
I am going to create a CSV file programmatically and would like to properly escape my strings before writing them.
I assume I'll need to escape commas and probably need to surround each value in single or double quotes (and thus will need to escape those too). Plus any carriage return / new line constants.
I was going to write it all myself but then found this in Objective-C and said why not just convert it, as it looks quite thorough:
-(NSString *)escapeString:(NSString *)s
{
NSString * escapedString = s;
BOOL containsSeperator = !NSEqualRanges([s rangeOfString:#","], NSMakeRange(NSNotFound, 0));
BOOL containsQuotes = !NSEqualRanges([s rangeOfString:#"\""], NSMakeRange(NSNotFound, 0));
BOOL containsLineBreak = !NSEqualRanges([s rangeOfString:#"\n"], NSMakeRange(NSNotFound, 0));
if (containsQuotes) {
escapedString = [escapedString stringByReplacingOccurrencesOfString:#"\"" withString:#"\"\""];
}
if (containsSeperator || containsLineBreak) {
escapedString = [NSString stringWithFormat:#"\"%#\"", escapedString];
}
return escapedString;
}
Before I go and convert this, however, I wanted to ask the community if there is an easier way now that we're in Swift 2. Have any interesting/new changes occurred for strings that I might want to consider in favor of "Swiftifying" the above code? I did some Googling but nothing jumped out at me and I want to really make sure I do a good job here. :-)
Thanks!
You could reduce your code and save it as a String extension:
extension String {
func escapeString() -> String {
var newString = self.stringByReplacingOccurrencesOfString("\"", withString: "\"\"")
if newString.containsString(",") || newString.containsString("\n") {
newString = String(format: "\"%#\"", newString)
}
return newString
}
}
Also few tests:
var test1 = String("Test")
test1.escapeString() // produces Test
var test2 = String("Test\n")
test2.escapeString() // produces "Test\n"
var test3 = String("Test, Test2")
test3.escapeString() // produces "Test, Test2"
So I have an array of elements of type float. And I have a UILabel which is supposed to display each of these elements of the array on DIFFERENT LINES.
The Array is
var history = [Float]()
I used a for loop to go through each element and append it to the UILabel
for(i=0; i<size; i++){
currentString = String(history[i])
result.text = result.text! + "\n" + currentString
}
result is the UILabel.
I tried using \n but it doesn't seem to recognise it. Any solutions for this in Swift. Thanks in advance!
You can try below to solve your issue.
let history = [1.0, 2.0, 3.0, 4.0]
var result = ""
self.lbl.text = ""
for var i=0; i < history.count; i++
{
let currentString = NSString(format: "%.2f", history[i])
self.lbl.text = self.lbl.text! + "\n" + (currentString as String)
}
And Line Number should be 0. I set that from XIB.
Thanks
The first thing I would check is if your label has (it is stupid mistake, but can happen to all of us)
label.numberOfLines = 0
Assuming that is true, instead of building the string by hand, you could use in-built function join(). Sadly, since it is not String array, you can't use it directly, but you have to create string array first
// Get both storages
var history = [Float]() // Filled with your data
var stringHistory = [String]()
// Convert each number to string
for value in history {
stringHistory.append(String(value))
}
// Finally, join array to one string using \n as separator
let finalString = "\n".join(stringHistory)
Hope some of this helps!