Swift 3: split a string to array by number [closed] - swift

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a string let string = "!101eggs". Now, I want to have an array like this ["!", "101", "e", "g", "g", "s"]. How can I do this?

I presume the hard part for you is "Where's the number"? As long as this is just a simple sequence of digits, a regular expression makes it easy to find:
let string = "!101eggs"
let patt = "\\d+"
let reg = try! NSRegularExpression(pattern:patt)
let r = reg.rangeOfFirstMatch(in: string,
options: [],
range: NSMakeRange(0,string.utf16.count)) // {1,3}
So now you know that the number starts at position 1 and is 3 characters long. The rest is left as an exercise for the reader.

Sorry It's too long
when input is
print("-1-2a000+4-1/000!00005gf101eg14g1s46nj3j4b1j5j23jj212j4b2j41234j01010101g0000z00005g0000".toArrayByNumber())
Result: ["-", "1", "-", "2", "a", "000", "+", "4", "-", "1", "/", "000", "!", "00005", "g", "f", "101", "e", "g", "14", "g", "1", "s", "46", "n", "j", "3", "j", "4", "b", "1", "j", "5", "j", "23", "j", "j", "212", "j", "4", "b", "2", "j", "41234", "j", "01010101", "g", "0000", "z", "00005", "g", "0000"]
extension Int {
func toZeroString() -> String {
return (0 ..< self).reduce("", { (result, zero) -> String in
return result + "0"
})
}
}
extension String {
func toArrayByNumber() -> [String] {
var array: [String] = []
var num = 0
var zeroCount = 0
var zeroEnd = false
for char in self.characters {
if let number = Int("\(char)") {
if zeroEnd == false && number == 0 {
zeroCount += 1
} else {
num = num * 10 + number
zeroEnd = true
}
} else {
if num != 0 {
array.append(zeroCount.toZeroString() + ("\(num)"))
} else if zeroCount > 0 {
array.append(zeroCount.toZeroString())
}
array.append(String(char))
num = 0
zeroCount = 0
zeroEnd = false
}
}
if num != 0 {
array.append(zeroCount.toZeroString() + ("\(num)"))
} else if zeroCount > 0 {
array.append(zeroCount.toZeroString())
}
return array
}
}

Related

Insert row in UITableViewController without replacing row - SWIFT

In my app I have a data pull from Firebase. I have a UITableViewController and would like to insert in a row a text from within the app. The data pull would be like this (please excuse the bad example but I cannot go into too much detail ..)
The original data pull:
Row 1: abc
Row 2: def
Row 3: ghi
Row 4: jkl
Row 5: mno
What I would like to achieve:
Row 1: abc
Row 2: def
Row 3: text from the app
Row 4: ghi
Row 5: jkl
Row 6: text from the app
Row 7: mno
How can I achieve this? I was trying to do something like this in cellForRowAt
if indexPath.row % 3 == 0 {
cell.text = "custom text"
}
But this is replacing every 3rd rows content. I would like to put a row in between, so to speak.
You can modify your server data with local data.
var serverData = ["a","b","c","d","e","f","g","h","i","j","k","l","m"]
let localAppData = ["1","2","3","4","5","6","7","8","9","10"]
var modified = [String]()
var counter = 0
for index in 1...serverData.count {
let value = serverData[index - 1]
if index % 3 == 0 && index != 0 {
if counter < localAppData.count {
modified.append(localAppData[counter])
}else{
modified.append(value)
}
counter += 1
}else{
modified.append(value)
}
}
serverData.removeAll()
serverData.append(contentsOf: modified)
print(serverData) //["a", "b", "1", "d", "e", "2", "g", "h", "3", "j", "k", "4", "m"]
if counter < localAppData.count {
// Appeds the remain local data to your serverData
serverData.append(contentsOf: localAppData[counter...localAppData.count-1])
}
print(serverData) //["a", "b", "1", "d", "e", "2", "g", "h", "3", "j", "k", "4", "m", "5", "6", "7", "8", "9", "10"]
Note: After modification you have to reload the tableView
You can update the datasource by inserting the value at 3rd position and use that datasource in cellforrowat
var a = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
var temp = a
for (ind, _) in a.enumerated() {
if ind % 3 == 0 && ind != 0 {
temp.insert("current text", at: ind)
}
}
print(temp) // Prints ["a", "b", "c", "current text", "d", "e", "current text", "f", "g", "h", "i"]

String sort using CharacterSet order

I am trying to alphabetically sort an array of non-English strings which contain a number of special Unicode characters. I can create a CharacterSet sequence which contains the desired lexicographic sort order.
Is there an approach in Swift5 to performing this type of customized sort?
I believe I saw such a function some years back, but a pretty exhaustive search today failed to turn anything up.
Any pointers would be appreciated!
As a simple implementation of matt's cosorting comment:
// You have `t` twice in your string; I've removed the first one.
let alphabet = "ꜢjiyꜤwbpfmnRrlhḥḫẖzsšqkgtṯdḏ "
// Map characters to their location in the string as integers
let order = Dictionary(uniqueKeysWithValues: zip(alphabet, 0...))
// Make the alphabet backwards as a test string
let string = alphabet.reversed()
// This sorts unknown characters at the end. Or you could throw instead.
let sorted = string.sorted { order[$0] ?? .max < order[$1] ?? .max }
print(sorted)
Rather than building your own “non-English” sorting, you might consider localized comparison. E.g.:
let strings = ["a", "á", "ä", "b", "c", "d", "e", "é", "f", "r", "s", "ß", "t"]
let result1 = strings.sorted()
print(result1) // ["a", "b", "c", "d", "e", "f", "r", "s", "t", "ß", "á", "ä", "é"]
let result2 = strings.sorted {
$0.localizedCaseInsensitiveCompare($1) == .orderedAscending
}
print(result2) // ["a", "á", "ä", "b", "c", "d", "e", "é", "f", "r", "s", "ß", "t"]
let locale = Locale(identifier: "sv")
let result3 = strings.sorted {
$0.compare($1, options: .caseInsensitive, locale: locale) == .orderedAscending
}
print(result3) // ["a", "á", "b", "c", "d", "e", "é", "f", "r", "s", "ß", "t", "ä"]
And a non-Latin example:
let strings = ["あ", "か", "さ", "た", "い", "き", "し", "ち", "う", "く", "す", "つ", "ア", "カ", "サ", "タ", "イ", "キ", "シ", "チ", "ウ", "ク", "ス", "ツ", "が", "ぎ"]
let result4 = strings.sorted {
$0.localizedCaseInsensitiveCompare($1) == .orderedAscending
}
print(result4) // ["あ", "ア", "い", "イ", "う", "ウ", "か", "カ", "が", "き", "キ", "ぎ", "く", "ク", "さ", "サ", "し", "シ", "す", "ス", "た", "タ", "ち", "チ", "つ", "ツ"]

How to sort a multidimensional character array alphabetically Swift

I am trying to sort a [[Character]] array that has random characters put in to it so that it is all alphabetical. ex output for right now:
["H", "P", "C"]
["F", "K", "V"]
["J", "Y", "B"]
I need it to be like this
["A", "B", "C"]
["D", "E", "F"]
["G", "H", "I"]
Any Ideas?
Please check :
let input = [["H", "P", "C"], ["F", "K", "V"], ["J", "Y", "B"], ["A", "L"]]
var sortedArray = input.flatMap({ $0 }).sorted()
var finalArray:[[String]]=[]
var subArray:[String]=[]
for i in 0..<sortedArray.count {
subArray.append(sortedArray[i])
if subArray.count == 3 || i == sortedArray.count-1 {
finalArray.append(subArray)
subArray = []
}
}
print(finalArray)
// Output : [["A", "B", "C"], ["F", "H", "J"], ["K", "L", "P"], ["V", "Y"]]
func flattenArray(nestedArray: [[Character]]) -> [[Character]]{
var myFlattendArray = [Character]()
var sortedArray = [[Character]]()
for element in nestedArray{
if element is [Character]{
for char in element{
myFlattendArray.append(char)
}
}
}
myFlattendArray = myFlattendArray.sorted(by: {$0 < $1})
var arrayForArray = [Character]()
for i in 0..<myFlattendArray.count{
if((i % nestedArray.count == 0 && i != 0)){
sortedArray.append(arrayForArray)
arrayForArray.removeAll()
}else if i == myFlattendArray.count - 1{
arrayForArray.append(myFlattendArray[i])
sortedArray.append(arrayForArray)
arrayForArray.removeAll()
}
arrayForArray.append(myFlattendArray[i])
}
return sortedArray
}
You can use flatMap to flatten your array, sort it and then you can group using this extension from this answer as follow:
extension Array {
func group(of n: IndexDistance) -> Array<Array> {
return stride(from: 0, to: count, by: n)
.map { Array(self[$0..<Swift.min($0+n, count)]) }
}
}
let arr = [["H", "P", "C"],
["F", "K", "V"],
["J", "Y", "B"]]
let sorted = arr.flatMap{$0}.sorted().group(of: 3)
sorted // [["B", "C", "F"], ["H", "J", "K"], ["P", "V", "Y"]]

How to check if string contains a certain character?

I've been trying to find this but I can't. I have the code:
func ayylmao(vorno: String){
if (vorno.(WHATEVER THE FUNCTION FOR FINDING A STRING GOES HERE)("a", "e", "i", "o", "u"))
{
print("Input Includes vowels")
}
}
but right at the if statement I can't find anything to check if the characters are in the string.
Like this:
let s = "hello"
let ok = s.characters.contains {"aeiou".characters.contains($0)} // true
I suggest two implementations:
func numberOfVowelsIn(_ string: String) -> Int {
let vowels: [Character] = ["a", "e", "i", "o", "u", "y", "A", "E", "I", "O", "U", "Y"]
return string.reduce(0, { $0 + (vowels.contains($1) ? 1 : 0) })
}
numberOfVowelsIn("hello my friend") //returns 5.
... and the second one with this code snippet hereafter to reach your goal:
let isVowel: (Character) -> Bool = { "aeiouyAEIOUY".contains($0) }
isVowel("B") //returns 'false'.
isVowel("a") //returns 'true'.
isVowel("U") //returns 'true'.

Why does UInt32(stringArray.count) count wrong in a function but correct alone in swift playground?

Why does this code count 6 elements, as 9 ("wrong") in swift playground.
var stringArray = ["1", "2", "3", "4", "5", "6"]
for var i = 0; i < 3; i++ {
stringArray.append("Paragraph" + "\(i)")
}
func concat (array: [String]) -> String {
let count = UInt32(stringArray.count) ** --> =9 **
let randomNumberOne = Int(arc4random_uniform(count))
let randomNumberTwo = Int(arc4random_uniform(count))
let randomNumberThree = Int(arc4random_uniform(count))
let concatString = array[randomNumberOne] + array[randomNumberTwo] + array[randomNumberThree]
return concatString
}
let finalString = concat(stringArray)
...but count this code as 6 (correct)
var stringArray = ["1", "2", "3", "4", "5", "6"] ** --> =6 **
let count = UInt32(stringArray.count)
Does it have something to do with 64 vs 32 bit? I have Xcode Version 6.0 (6A313).
You are appending new elements to the same stringArray which already has content ["1", "2", "3", "4", "5", "6"]. Then you append the "paragraph (i)" string to it 3 times. So, the new content is now, ["1", "2", "3", "4", "5", "6", "Paragraph 1", "Paragraph 2", "Paragraph 3"]. Thats how the count reached to 9.