How to convert NSString to Character in Swift? - string

I want to convert NSString to Character in Swift.
I am getting a String from NSTextField, where I input a single character (Example "#"), I need this in Character type.

Use Character class
var chars = [Character](str)

this should be as simple as let characterFromString = Character(textField.text).
NSString is automatically bridged to Swift's String, and the Character class has an init which accepts a single character String; see the documentation here.
This requires that the input string contain a single grapheme cluster (i.e. a single character) and so you might want to validate your input before casting. A slightly more verbose version of the above would be:
let text = textField.text as String
if countElements(text) == 1 {
let character = Character(text)
// do what you want
} else {
// bad input :-(
}

The stringValue of NSTextField actually returns a Swift string and not NSString:
let str = myTextField.stringValue // str is a String
You get the first element with
let ch = str[str.startIndex] // ch is a Character
A NSString would have to be converted to a Swift string first:
let nsString : NSString = "#"
let str = String(nsString)
let ch = str[str.startIndex]

Related

Replace some characters in a string with the next unicode character

I have an input text as following:
inputtext = "This is a test";
I need to replace some of the character (based on a certain criteria) to next unicode character
let i = 0;
for c in inputtext.chars() {
if (somecondition){
// Replace char here
inputtext.replace_range(i..i+1, newchar);
// println!("{}", c);
}
What is the best way to do this?
You can't easily update a string in-place because a Rust string is not just an array of characters, it's an array of bytes (in UTF-8 encoding), and different characters may use different numbers of bytes. For example, the character ߿ (U+07FF "Nko Taman Sign") uses two bytes, whereas the next Unicode character ࠀ (U+0800 "Samaritan Letter Alaf") uses three.
It's therefore simplest to turn the string into an iterator of characters (using .chars()), manipulate that iterator as appropriate, and then construct a new string using .collect().
For example:
let old = "abcdef";
let new = old.chars()
// note: there's an edge case if ch == char::MAX which we must decide
// how to handle. in this case I chose to not change the
// character, but this may be different from what you need.
.map(|ch| {
if somecondition {
char::from_u32(ch as u32 + 1).unwrap_or(ch)
} else {
ch
}
})
.collect::<String>();

How to collect a string to a stack of characters in Java 8? [duplicate]

I would like to convert the string containing abc to a list of characters and a hashset of characters. How can I do that in Java ?
List<Character> charList = new ArrayList<Character>("abc".toCharArray());
In Java8 you can use streams I suppose.
List of Character objects:
List<Character> chars = str.chars()
.mapToObj(e->(char)e).collect(Collectors.toList());
And set could be obtained in a similar way:
Set<Character> charsSet = str.chars()
.mapToObj(e->(char)e).collect(Collectors.toSet());
You will have to either use a loop, or create a collection wrapper like Arrays.asList which works on primitive char arrays (or directly on strings).
List<Character> list = new ArrayList<Character>();
Set<Character> unique = new HashSet<Character>();
for(char c : "abc".toCharArray()) {
list.add(c);
unique.add(c);
}
Here is an Arrays.asList like wrapper for strings:
public List<Character> asList(final String string) {
return new AbstractList<Character>() {
public int size() { return string.length(); }
public Character get(int index) { return string.charAt(index); }
};
}
This one is an immutable list, though. If you want a mutable list, use this with a char[]:
public List<Character> asList(final char[] string) {
return new AbstractList<Character>() {
public int size() { return string.length; }
public Character get(int index) { return string[index]; }
public Character set(int index, Character newVal) {
char old = string[index];
string[index] = newVal;
return old;
}
};
}
Analogous to this you can implement this for the other primitive types.
Note that using this normally is not recommended, since for every access you
would do a boxing and unboxing operation.
The Guava library contains similar List wrapper methods for several primitive array classes, like Chars.asList, and a wrapper for String in Lists.charactersOf(String).
The lack of a good way to convert between a primitive array and a collection of its corresponding wrapper type is solved by some third party libraries. Guava, a very common one, has a convenience method to do the conversion:
List<Character> characterList = Chars.asList("abc".toCharArray());
Set<Character> characterSet = new HashSet<Character>(characterList);
Use a Java 8 Stream.
myString.chars().mapToObj(i -> (char) i).collect(Collectors.toList());
Breakdown:
myString
.chars() // Convert to an IntStream
.mapToObj(i -> (char) i) // Convert int to char, which gets boxed to Character
.collect(Collectors.toList()); // Collect in a List<Character>
(I have absolutely no idea why String#chars() returns an IntStream.)
The most straightforward way is to use a for loop to add elements to a new List:
String abc = "abc";
List<Character> charList = new ArrayList<Character>();
for (char c : abc.toCharArray()) {
charList.add(c);
}
Similarly, for a Set:
String abc = "abc";
Set<Character> charSet = new HashSet<Character>();
for (char c : abc.toCharArray()) {
charSet.add(c);
}
List<String> result = Arrays.asList("abc".split(""));
Create an empty list of Character and then make a loop to get every character from the array and put them in the list one by one.
List<Character> characterList = new ArrayList<Character>();
char arrayChar[] = abc.toCharArray();
for (char aChar : arrayChar)
{
characterList.add(aChar); // autoboxing
}
You can do this without boxing if you use Eclipse Collections:
CharAdapter abc = Strings.asChars("abc");
CharList list = abc.toList();
CharSet set = abc.toSet();
CharBag bag = abc.toBag();
Because CharAdapter is an ImmutableCharList, calling collect on it will return an ImmutableList.
ImmutableList<Character> immutableList = abc.collect(Character::valueOf);
If you want to return a boxed List, Set or Bag of Character, the following will work:
LazyIterable<Character> lazyIterable = abc.asLazy().collect(Character::valueOf);
List<Character> list = lazyIterable.toList();
Set<Character> set = lazyIterable.toSet();
Bag<Character> set = lazyIterable.toBag();
Note: I am a committer for Eclipse Collections.
IntStream can be used to access each character and add them to the list.
String str = "abc";
List<Character> charList = new ArrayList<>();
IntStream.range(0,str.length()).forEach(i -> charList.add(str.charAt(i)));
Using Java 8 - Stream Funtion:
Converting A String into Character List:
ArrayList<Character> characterList = givenStringVariable
.chars()
.mapToObj(c-> (char)c)
.collect(collectors.toList());
Converting A Character List into String:
String givenStringVariable = characterList
.stream()
.map(String::valueOf)
.collect(Collectors.joining())
To get a list of Characters / Strings -
List<String> stringsOfCharacters = string.chars().
mapToObj(i -> (char)i).
map(c -> c.toString()).
collect(Collectors.toList());

Defining a custom PURE Swift Character Set

So, using Foundation you can use NSCharacterSet to define character sets and test character membership in Strings. I would like to do so without Cocoa classes, but in a purely Swift manner.
Ideally, code could be used like so:
struct ReservedCharacters: CharacterSet {
characters "!", "#", "$", "&", ... etc.
func isMember(character: Character) -> Bool
func encodeCharacter(parameters) { accepts a closure }
func decodeCharacter(parameters) { accepts a closure }
}
This is probably a very loaded question. But I'd like to see what you Swifters think.
You can already test for membership in a character set by initializing a String and using the contains global function:
let vowels = "aeiou"
let isVowel = contains(vowels, "i") // isVowel == true
As far as your encode and decode functions go, are you just trying to get the 8-bit or 16-bit encodings for the Character? If that is the case then just convert them to a String and access there utf8 or utf16 properties:
let char = Character("c")
let a = Array(String(char).utf8)
println() // This prints [99]
Decode would take a little more work, but I know there's a function for it...
Edit: This will replace a character from a characterSet with '%' followed by the character's hex value:
let encode: String -> String = { s in
reduce(String(s).unicodeScalars, "") { x, y in
switch contains(charSet, Character(y)) {
case true:
return x + "%" + String(y.value, radix: 16)
default:
return x + String(y)
}
}
}
let badURL = "http://why won't this work.com"
let encoded = encode(badURL)
println(encoded) // prints "http://why%20won%27t%20this%20work.com"
Decoding, again, is a bit more challenging, but I'm sure it can be done...

String interpolation in Swift

A function in swift takes any numeric type in Swift (Int, Double, Float, UInt, etc).
the function converts the number to a string
the function signature is as follows :
func swiftNumbers <T : NumericType> (number : T) -> String {
//body
}
NumericType is a custom protocol that has been added to numeric types in Swift.
inside the body of the function, the number should be converted to a string:
I use the following
var stringFromNumber = "\(number)"
which is not so elegant, PLUS : if the absolute value of the number is strictly inferior to 0.0001 it gives this:
"\(0.000099)" //"9.9e-05"
or if the number is a big number :
"\(999999999999999999.9999)" //"1e+18"
is there a way to work around this string interpolation limitation? (without using Objective-C)
P.S :
NumberFormater doesn't work either
import Foundation
let number : NSNumber = 9_999_999_999_999_997
let formatter = NumberFormatter()
formatter.minimumFractionDigits = 20
formatter.minimumIntegerDigits = 20
formatter.minimumSignificantDigits = 40
formatter.string(from: number) // "9999999999999996.000000000000000000000000"
let stringFromNumber = String(format: "%20.20f", number) // "0.00000000000000000000"
Swift String Interpolation
1) Adding different types to a string
2) Means the string is created from a mix of constants, variables, literals or expressions.
Example:
let length:Float = 3.14
var breadth = 10
var myString = "Area of a rectangle is length*breadth"
myString = "\(myString) i.e. = \(length)*\(breadth)"
Output:
3.14
10
Area of a rectangle is length*breadth
Area of a rectangle is length*breadth i.e. = 3.14*10
Use the Swift String initializer: String(format: <#String#>, arguments: <#[CVarArgType]#>)
For example:
let stringFromNumber = String(format: "%.2f", number)
String and Characters conforms to StringInterpolationProtocol protocol which provide more power to the strings.
StringInterpolationProtocol - "Represents the contents of a string literal with interpolations while it’s being built up."
String interpolation has been around since the earliest days of Swift, but in Swift 5.0 it’s getting a massive overhaul to make it faster and more powerful.
let name = "Ashwinee Dhakde"
print("Hello, I'm \(name)")
Using the new string interpolation system in Swift 5.0 we can extend String.StringInterpolation to add our own custom interpolations, like this:
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: Date) {
let formatter = DateFormatter()
formatter.dateStyle = .full
let dateString = formatter.string(from: value)
appendLiteral(dateString)
}
}
Usage: print("Today's date is \(Date()).")
We can even provide user-defined names to use String-Interpolation, let's understand with an example.
extension String.StringInterpolation {
mutating func appendInterpolation(JSON JSONData: Data) {
guard
let JSONObject = try? JSONSerialization.jsonObject(with: JSONData, options: []),
let jsonData = try? JSONSerialization.data(withJSONObject: JSONObject, options: .prettyPrinted) else {
appendInterpolation("Invalid JSON data")
return
}
appendInterpolation("\n\(String(decoding: jsonData, as: UTF8.self))")
}
}
print("The JSON is \(JSON: jsonData)")
Whenever we want to provide "JSON" in the string interpolation statement, it will print the .prettyPrinted
Isn't it cool!!

Remove last character from string. Swift language

How can I remove last character from String variable using Swift? Can't find it in documentation.
Here is full example:
var expression = "45+22"
expression = expression.substringToIndex(countElements(expression) - 1)
Swift 4.0 (also Swift 5.0)
var str = "Hello, World" // "Hello, World"
str.dropLast() // "Hello, Worl" (non-modifying)
str // "Hello, World"
String(str.dropLast()) // "Hello, Worl"
str.remove(at: str.index(before: str.endIndex)) // "d"
str // "Hello, Worl" (modifying)
Swift 3.0
The APIs have gotten a bit more swifty, and as a result the Foundation extension has changed a bit:
var name: String = "Dolphin"
var truncated = name.substring(to: name.index(before: name.endIndex))
print(name) // "Dolphin"
print(truncated) // "Dolphi"
Or the in-place version:
var name: String = "Dolphin"
name.remove(at: name.index(before: name.endIndex))
print(name) // "Dolphi"
Thanks Zmey, Rob Allen!
Swift 2.0+ Way
There are a few ways to accomplish this:
Via the Foundation extension, despite not being part of the Swift library:
var name: String = "Dolphin"
var truncated = name.substringToIndex(name.endIndex.predecessor())
print(name) // "Dolphin"
print(truncated) // "Dolphi"
Using the removeRange() method (which alters the name):
var name: String = "Dolphin"
name.removeAtIndex(name.endIndex.predecessor())
print(name) // "Dolphi"
Using the dropLast() function:
var name: String = "Dolphin"
var truncated = String(name.characters.dropLast())
print(name) // "Dolphin"
print(truncated) // "Dolphi"
Old String.Index (Xcode 6 Beta 4 +) Way
Since String types in Swift aim to provide excellent UTF-8 support, you can no longer access character indexes/ranges/substrings using Int types. Instead, you use String.Index:
let name: String = "Dolphin"
let stringLength = count(name) // Since swift1.2 `countElements` became `count`
let substringIndex = stringLength - 1
name.substringToIndex(advance(name.startIndex, substringIndex)) // "Dolphi"
Alternatively (for a more practical, but less educational example) you can use endIndex:
let name: String = "Dolphin"
name.substringToIndex(name.endIndex.predecessor()) // "Dolphi"
Note: I found this to be a great starting point for understanding String.Index
Old (pre-Beta 4) Way
You can simply use the substringToIndex() function, providing it one less than the length of the String:
let name: String = "Dolphin"
name.substringToIndex(countElements(name) - 1) // "Dolphi"
The global dropLast() function works on sequences and therefore on Strings:
var expression = "45+22"
expression = dropLast(expression) // "45+2"
// in Swift 2.0 (according to cromanelli's comment below)
expression = String(expression.characters.dropLast())
Swift 4:
let choppedString = String(theString.dropLast())
In Swift 2, do this:
let choppedString = String(theString.characters.dropLast())
I recommend this link to get an understanding of Swift strings.
Swift 4/5
var str = "bla"
str.removeLast() // returns "a"; str is now "bl"
This is a String Extension Form:
extension String {
func removeCharsFromEnd(count_:Int) -> String {
let stringLength = count(self)
let substringIndex = (stringLength < count_) ? 0 : stringLength - count_
return self.substringToIndex(advance(self.startIndex, substringIndex))
}
}
for versions of Swift earlier than 1.2:
...
let stringLength = countElements(self)
...
Usage:
var str_1 = "Maxim"
println("output: \(str_1.removeCharsFromEnd(1))") // "Maxi"
println("output: \(str_1.removeCharsFromEnd(3))") // "Ma"
println("output: \(str_1.removeCharsFromEnd(8))") // ""
Reference:
Extensions add new functionality to an existing class, structure, or enumeration type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling). Extensions are similar to categories in Objective-C. (Unlike Objective-C categories, Swift extensions do not have names.)
See DOCS
Use the function removeAtIndex(i: String.Index) -> Character:
var s = "abc"
s.removeAtIndex(s.endIndex.predecessor()) // "ab"
Swift 4
var welcome = "Hello World!"
welcome = String(welcome[..<welcome.index(before:welcome.endIndex)])
or
welcome.remove(at: welcome.index(before: welcome.endIndex))
or
welcome = String(welcome.dropLast())
The easiest way to trim the last character of the string is:
title = title[title.startIndex ..< title.endIndex.advancedBy(-1)]
import UIKit
var str1 = "Hello, playground"
str1.removeLast()
print(str1)
var str2 = "Hello, playground"
str2.removeLast(3)
print(str2)
var str3 = "Hello, playground"
str3.removeFirst(2)
print(str3)
Output:-
Hello, playgroun
Hello, playgro
llo, playground
let str = "abc"
let substr = str.substringToIndex(str.endIndex.predecessor()) // "ab"
var str = "Hello, playground"
extension String {
var stringByDeletingLastCharacter: String {
return dropLast(self)
}
}
println(str.stringByDeletingLastCharacter) // "Hello, playgroun"
Short answer (valid as of 2015-04-16): removeAtIndex(myString.endIndex.predecessor())
Example:
var howToBeHappy = "Practice compassion, attention and gratitude. And smile!!"
howToBeHappy.removeAtIndex(howToBeHappy.endIndex.predecessor())
println(howToBeHappy)
// "Practice compassion, attention and gratitude. And smile!"
Meta:
The language continues its rapid evolution, making the half-life for many formerly-good S.O. answers dangerously brief. It's always best to learn the language and refer to real documentation.
With the new Substring type usage:
Swift 4:
var before: String = "Hello world!"
var lastCharIndex: Int = before.endIndex
var after:String = String(before[..<lastCharIndex])
print(after) // Hello world
Shorter way:
var before: String = "Hello world!"
after = String(before[..<before.endIndex])
print(after) // Hello world
Use the function advance(startIndex, endIndex):
var str = "45+22"
str = str.substringToIndex(advance(str.startIndex, countElements(str) - 1))
A swift category that's mutating:
extension String {
mutating func removeCharsFromEnd(removeCount:Int)
{
let stringLength = count(self)
let substringIndex = max(0, stringLength - removeCount)
self = self.substringToIndex(advance(self.startIndex, substringIndex))
}
}
Use:
var myString = "abcd"
myString.removeCharsFromEnd(2)
println(myString) // "ab"
Another way If you want to remove one or more than one character from the end.
var myStr = "Hello World!"
myStr = (myStr as NSString).substringToIndex((myStr as NSString).length-XX)
Where XX is the number of characters you want to remove.
Swift 3 (according to the docs) 20th Nov 2016
let range = expression.index(expression.endIndex, offsetBy: -numberOfCharactersToRemove)..<expression.endIndex
expression.removeSubrange(range)
The dropLast() function removes the last element of the string.
var expression = "45+22"
expression = expression.dropLast()
Swift 4.2
I also delete my last character from String (i.e. UILabel text) in IOS app
#IBOutlet weak var labelText: UILabel! // Do Connection with UILabel
#IBAction func whenXButtonPress(_ sender: UIButton) { // Do Connection With X Button
labelText.text = String((labelText.text?.dropLast())!) // Delete the last caracter and assign it
}
I'd recommend using NSString for strings that you want to manipulate. Actually come to think of it as a developer I've never run into a problem with NSString that Swift String would solve... I understand the subtleties. But I've yet to have an actual need for them.
var foo = someSwiftString as NSString
or
var foo = "Foo" as NSString
or
var foo: NSString = "blah"
And then the whole world of simple NSString string operations is open to you.
As answer to the question
// check bounds before you do this, e.g. foo.length > 0
// Note shortFoo is of type NSString
var shortFoo = foo.substringToIndex(foo.length-1)
Swift 3: When you want to remove trailing string:
func replaceSuffix(_ suffix: String, replacement: String) -> String {
if hasSuffix(suffix) {
let sufsize = suffix.count < count ? -suffix.count : 0
let toIndex = index(endIndex, offsetBy: sufsize)
return substring(to: toIndex) + replacement
}
else
{
return self
}
}
complimentary to the above code I wanted to remove the beginning of the string and could not find a reference anywhere. Here is how I did it:
var mac = peripheral.identifier.description
let range = mac.startIndex..<mac.endIndex.advancedBy(-50)
mac.removeRange(range) // trim 17 characters from the beginning
let txPower = peripheral.advertisements.txPower?.description
This trims 17 characters from the beginning of the string (he total string length is 67 we advance -50 from the end and there you have it.
I prefer the below implementation because I don't have to worry even if the string is empty
let str = "abc"
str.popLast()
// Prints ab
str = ""
str.popLast() // It returns the Character? which is an optional
// Print <emptystring>

Resources