SWIFT: performance of uppercaseString - string

I have a large file (25 MB) of text. I read it into a NSString var. I want to use "uppercaseString" to convert every char to upper case. But the function in so terribly slow, it needs minutes.
Any tip to get it work much faster?
Added code:
if let path = NSBundle.mainBundle().pathForResource("GERMANU", ofType: "txt") {
var error: NSError?
if let data = NSData(contentsOfFile: path, options: NSDataReadingOptions(), error: &error) {
if let datastring = NSString(data: data, encoding: NSMacOSRomanStringEncoding) {
var upper = datastring.uppercaseString
...
That's the code which works, but is slow. Only last row needs all the time.

String::uppercaseString is instantaneous; creating the string is not.
# Long time
12> var st : String = "".join(Array(count:25000000, repeatedValue: "a"))
st: String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa..."
# Short time
13> st.uppercaseString
$R8: String = "AAAAAAAAAAAAAAAAAAAAAAAAAAAA..."
Given that you are using the Roman encoding, it is possible that the conversion to uppercase is non-trivial. Perhaps you can try another encoding (if any others are appropriate)? You might try the init?(... usedEncoding ...) variant and invoke fastestEncoding on the result to explore a bit.
Note: you can create a Swift string directly from a file with a particular encoding using:
if let datastring = String(contentsOfFile: path, encoding: ... , error: &error) {
var upper = datastring.uppercaseString
}

To me it looks like a poor library implementation. Using NSString.uppercaseString() is realy fast (half a second). So I will use this, but I'm developing in Swift because I like the language. So I don't want to switch back to old stuff.

Related

Flutter String Concatenation breaking when last string is file extension

I'm trying to concatenate some strings which will eventually be part of a URL, but the result of the concatenation is always missing the last String which is a file extension.
I've tried all the official ways of concatenating. Here is my latest attempt when I tried to merge the strings by using the join method on a String List.
String? resColor = color?.label;
String? resCategory = category?.label;
print(resColor!.length);
List<String> refSplit = [
'previewAssets/',
resCategory!,
'/',
resColor!,
'.jpg'
];
for (int i = 0; i < refSplit.length; i++) {
print(refSplit[i]);
}
String ref = refSplit.join('');
print(refSplit);
print(ref);
My excepted outcome is obviously that ref would contain all items from refSplit. But it doesn't.
Here is the output from the prints: output
Im knida new to flutter but I feel like concatenating strings shouldn't be this hard, so I'm probably missing something obvious. Any help would be greatly appreciated.
*edit: So I've continued to look into this and I'm pretty sure the problem is with resColor, which suspiciously has a length of 4 when it should be 3. So my current guess is that it contains some invisible endline like char at the end which is messing up the concat.
**edit: By removing the last char of resColor, it fixed the issue. This is the code I used to do that: resColor = resColor!.substring( 0, resColor!.length -1);
I tried your code and it seems to work fine in dartpad
void main() {
List<String> refSplit = [
'previewAssets/',
'something',
'/',
'109',
'.jpg'
];
String ref = refSplit.join("");
print(ref);
}
Try to restart your IDE and try again.

Insert commas into string number

I have this code, and I want to put commas.
I've seen many examples, but I dont now were put the code.
This is my AS3 code:
calccn.addEventListener(MouseEvent.CLICK,result1);
function result1(e:MouseEvent)
{
var vev: Number = (Number(vev.text));
var cn1: Number = (Number(3/100));
var result1f: Number = (Number(vev*cn1));
var round;
round=result1f.toFixed(0);
v3.text = String(round);
}
Example
If the result give me 1528000,32
I want that the result is 1.528.000 or 1 528 000
I didn't know (live and learn, eh), but there's actually a dedicated class: NumberFormatter.
If you want to do the thing on a regular basis, you might want a method to call:
// Implementation.
import flash.globalization.NumberFormatter;
// The default separator is comma.
function formattedNumber(value:Number, separator:String = ","):String
{
var NF:NumberFormatter;
NF = new NumberFormatter("en_US");
// Enforce the use of the given separator.
NF.groupingSeparator = separator;
// Ignore the fraction part.
NF.fractionalDigits = 0;
return NF.formatNumber(value);
}
// Usage.
//Format the given number with spaces for separator.
trace(formattedNumber(1528000.32, " ")); // 1 528 000
//Format the given number with the default separator.
trace(formattedNumber(1528000.32)); // 1,528,000
But if you want just a simple one-timer, and don't really care if it is commas or spaces as long as they present you may just condense in into a single expression:
calccn.addEventListener(MouseEvent.CLICK, result1);
function result1(e:MouseEvent):void
{
// Declaring variables with the same names as
// other entities is a generally bad idea.
var input:Number = Number(vev.text);
var cn1:Number = 3.0 / 100.0;
// Keep in mind that I used int() here as
// a simple tool to remove the fraction part.
v3.text = (new NumberFormatter("en_US")).formatNumber(int(input * cn1));
}

Rust: How to concatenate bytes together

I have already read the following link but still get some errors with my current attempt:
let data = &[37u8, 42u8];
let data_two = &[0x34u8, 0x32u8];
let res:Vec<u8> = [data, data_two].concat();
Also, ideally I would like to avoid concatenation, and write an array of u8 to a buffer, where I reserve the first two bytes for storing length and index like:
let nb:u8 = get_chunks_nb();
let index:u8 = get_chunk_index();
let header = &[nb, index];
// this kind of things in C:
memcpy(&buffer, header, 2);
memcpy(&buffer[2], chunk, chunk_len);
Thank you for your help!
I took a shot at it, but I'm not 100% sure as to why, I'm still new to Rust.
It looks like the compiler is seeing data and data_two as arrays, and so [data, data_two] is then an array of array and not an array of slice. Which is probably why it couldn't find the concat method on it.
By explicitely saying that data is a slice, everything seems to fall into place:
let data:&[u8] = &[37u8, 42u8];
let data_two = &[0x34u8, 0x32u8];
let mut res:Vec<u8> = [data, data_two].concat();

How to include emoticons in Swift string?

Here is a pretty good article that references iOS emoticons and their code. For example \ue008 for the small camera.
I tried this in my code :
var myText: String = "\ue008"
This is not accepted by Xcode. How to include it ?
If I understand what you are trying to achieve, then:
Press "ctrl + cmd + space" while in XCode. A sample usage of 'hearts' emoticon
cell.textLabel?.text = "❀️" + " \(liker) liked \(userBeingliked)'s photo"
That's from swift documentation:
let dollarSign = "\u{24}" // $, Unicode scalar U+0024
let blackHeart = "\u{2665}" // β™₯, Unicode scalar U+2665
let sparklingHeart = "\u{1F496}" // πŸ’–, Unicode scalar U+1F496
You don't need the unicode constants at all. Just use the character viewer and type the character directly. 😝
let sparklingHeart = "πŸ’–"
1 Decoding the Unicode:
extension String {
var decodeEmoji: String{
let data = self.data(using: String.Encoding.utf8);
let decodedStr = NSString(data: data!, encoding: String.Encoding.nonLossyASCII.rawValue)
if let str = decodedStr{
return str as String
}
return self
}
}
Usage
let decodedString = yourString.decodeEmoji
2 Encoding the Unicode:
extension String {
var encodeEmoji: String{
if let encodeStr = NSString(cString: self.cString(using: .nonLossyASCII)!, encoding: String.Encoding.utf8.rawValue){
return encodeStr as String
}
return self
}
}
Usage
let encodedString = yourString.encodeEmoji
You could insert the emoji directly using ⌘ ^ Space.
Or, based on Greg's answer:
var myText: String = "\u{e008}"
As Greg posted above, you can directly input the emoji into Swift using the OSx character viewer. The character viewer is disabled by default. Here is how to enable it:
Go to System Preferences > Language and Region > Keyboard Preferences > Keyboard then check Show Keyboard, Emoji, & Symbol Viewers in menu bar. Once checked you can open the character viewer from the top right menu bar next to your Wifi and Date/Time icons.
from your Hex "0x1F52D" to actual Emoji
let c = 0x1F602
next step would possibly getting an Uint32 from your Hex
let intEmoji = UnicodeScalar(c!).value
from this you can do something like
titleLabel.text = String(UnicodeScalar(intEmoji)!)
here you have a "πŸ˜‚"
it work with range of hexadecimal too
let emojiRanges = [
0x1F600...0x1F636,
0x1F645...0x1F64F,
0x1F910...0x1F91F,
0x1F30D...0x1F52D
]
for range in emojiRanges {
for i in range {
let c = UnicodeScalar(i)!.value
data.append(c)
}
}
to get multiple UInt32 from your Hex range for exemple
Chris Slowik's and Greg's answers are close.
The easiest answer is just to "rephrase" your String from this:
var myText: String = "\ue008"
To this:
var myText: String = "\u{008}"
The Unicodes found on the link you've attached are not wrong, as someone else claimed. You just need to rephrase it inside the String.
The important piece of code in your example above is the "008" part.
I've created a simple function to convert these kinds Unicode to their corresponding Emojis:
func convertHexToEmoji(_ u:Int) -> String {
return "\(UnicodeScalar(u)!)" }
To use:
let myText = convertHexToEmoji(008)
print(myText)
This took me a bit of time to figure out in MacOS 11, so I thought I would share.
If you prefer to input the unicode characters rather than pasting literal emojis, you can find out the unicode for the system emojis like this:
Focus/click into a text field (e.g. the search bar in your web browser).
Press ctrl+cmd+space or go to Edit->Emoji & Symbols in the menu bar.
Scroll up in the character viewer until you see the window expand icon in the upper right:
In the expanded Character Viewer window, press the upper left button and select Customize List....
Scroll down to Code Tables minimized list, expand the list, toggle on Unicode, and press Done (system changed this window to dark mode for whatever reason).
Now, click the different emojis and you should see the unicode underneath the image.
Then you inject it the unicode like this:
var myText: String = "\u{e008}"

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!!

Resources