Have to count a character occurrence in Nim string type - nim-lang

How to count a character occurrence in string in Nim, mainly using its native statements prior go to module ? eg.
var
str = "Hello World"
c : int
c = numChar( "o", str ) # <- illustration only ?

The earlier answer is correct but if you do not want to import any modules you can write your own procedure:
proc count_char(value: string = "Hello World", ch: char = 'o'): int =
var cnt_c: int = 0
for c in value:
if c == ch:
cnt_c += 1
result = cnt_c
var
val: string = "Mother Goose"
ch: char = 'o'
echo $count_char(val, ch)
PS: Unrelated - Need syntax highlight for nim-lang on SO.

Use the count function from strutils:
import std/strutils
let str = "Hello World"
let count = count(str, 'o')
assert count = 1
There’s also a string overload for counting sub strings as well.

Related

how to extract an integer range from a string

I have a string that contains different ranges and I need to find their value
var str = "some text x = 1..14, y = 2..4 some text"
I used the substringBefore() and substringAfter() methodes to get the x and y but I can't find a way to get the values because the numbers could be one or two digits or even negative numbers.
One approach is to use a regex, e.g.:
val str = "some text x = 1..14, y = 2..4 some text"
val match = Regex("x = (-?\\d+[.][.]-?\\d+).* y = (-?\\d+[.][.]-?\\d+)")
.find(str)
if (match != null)
println("x=${match.groupValues[1]}, y=${match.groupValues[2]}")
// prints: x=1..14, y=2..4
\\d matches a single digit, so \\d+ matches one or more digits; -? matches an optional minus sign; [.] matches a dot; and (…) marks a group that you can then retrieve from the groupValues property. (groupValues[0] is the whole match, so the individual values start from index 1.)
You could easily add extra parens to pull out each number separately, instead of whole ranges.
(You may or may not find this as readable or maintainable as string-manipulation approaches…)
Is this solution fit for you?
val str = "some text x = 1..14, y = 2..4 some text"
val result = str.replace(",", "").split(" ")
var x = ""; var y = ""
for (i in 0..result.count()-1) {
if (result[i] == "x") {
x = result[i+2]
} else if (result[i] == "y") {
y = result[i+2]
}
}
println(x)
println(y)
Using KotlinSpirit library
val rangeParser = object : Grammar<IntRange>() {
private var first: Int = -1
private var last: Int = -1
override val result: IntRange
get() = first..last
override fun defineRule(): Rule<*> {
return int {
first = it
} + ".." + int {
last = it
}
}
}.toRule().compile()
val str = "some text x = 1..14, y = 2..4 some text"
val ranges = rangeParser.findAll(str)
https://github.com/tiksem/KotlinSpirit

How to change the current character in "for char in string" Python 3

So given this example:
string = "string"
for char in string:
if char = "a":
# change current character to some other character
elif char = "b"
# change current character to some other character
how can I make it so that the current character of the string is replaced with some other string
("replace()" changes all of the character of the same type
Thanks
i didn't know that string are immutable but i found a workaround for this passing trough a list:
string = 'aa String aa'
string = list(string)
for index in range(len(string)):
if string[index] == 'a':
string[index] = 'c'
string = "".join(string)
maybe other method are faster but if you need to specifically loop though the string this would work fine.
If you don't want to use replace or a regex, you can use this code:
string = "abstring"
new_chars = []
for char in string:
if char == "a":
char = "b"
elif char == "b":
char = "c"
new_chars.append(char)
new_string = "".join(new_chars)
print(string, new_string)
Or you could actually use replace which has a count option:
string = "abstringab"
new_string = string.replace("a", "o", 1)
new_string = new_string.replace("b", "x", 1)
print(new_string)

Swift 5: identify all different substrings in string

I have the following string:
var strOfCharToSort = "azcdczbdxaaczdbbaazdz"
but I'm trying to get the count of the different substrings
for example:
let countofA = strOfCharToSort.filter { $0 == "a" }.count
and it works but I don't know what substrings are in the string I'm loading
I can sort the string:
strOfCharToSort = String(strOfCharToSort.sorted()) \\ result: aaaaabbbcccddddxzzzzz
But my question to guys there is a way to split the string when if finds a different substring?
I'll really appreciate you help.
let strOfCharToSort = "azcdczbdxaaczdbbaazdz"
let setOfChars = Set(strOfCharToSort)
let setOfCharsArray = Array(setOfChars).sorted()
let listOfSortedCharSubstrings = setOfCharsArray.map { (charachter) in
return strOfCharToSort.filter { $0 == charachter }
}
This is a solution to get the sub strings of a sorted character array.
Try This
let StringOfChar = "azcdczbdxaaczdbbaazdz"
let SetOfAllChar = Set(StringOfChar)
for char in SetOfAllChar {
let countofChar = StringOfChar.filter { $0 == char }.count
print("Count of \(char) : \(countofChar)")
}
Output:
Count of d: 4
Count of z: 5
Count of c: 3
Count of b: 3
Count of a: 5
Count of x: 1

In Swift NSAttributedString has more characters than String?

I am trying to add attributes to some ranges in Swift String.
I found ranges of first and last symbol in substring and color the text between them (including) in red.
let mutableString = NSMutableAttributedString(string: text)
let str = mutableString.string
//Red symbols
var t = 0
let symbols = mutableString.string.characters.count
while t < symbols {
if str[t] == "[" {
let startIndex = t
while str[t] != "]" {
t += 1
}
t += 1
let endIndex = t
mutableString.addAttribute(
NSForegroundColorAttributeName,
value: UIColor.redColor(),
range: NSMakeRange(startIndex, endIndex - startIndex))
}
t += 1
}
But I found that ranges in String and in NSMutableAttributedString are not equal. Range in String is shorter (this text is not in Unicode encoding).
Is there a some way to find ranges not in underlying String but in NSAttributedString to find it correctly?
Example:
print(mutableString.length) //550
print(mutableString.string.characters.count) //548
Why is this difference?
Yes it is possible to find ranges in NSMutableAttributedString.
Example :
let text = "[I love Ukraine!]"
var start = text.rangeOfString("[")
var finish = text.rangeOfString("]")
let mutableString = NSMutableAttributedString(string: text)
let startIndex = mutableString.string.rangeOfString("[")
let finishIndex = mutableString.string.rangeOfString("]")
Example output from playground:
Distinguish between String and NSString, even though they are bridged to one another. String is native Swift, and you define a range in terms of String character index. NSString is Cocoa (Foundation), and you define a range in terms of NSRange.
Yes, I found it.
Windows end-of-line "\r\n" is two symbols in NSAttributedString but only one character in Swift String.
I use checking in my code:
let symbols = mutableString.string.characters.count
var extendedSymbols = 0
while t < symbols {
if str[t] == "\r\n" { extendedSymbols += 1 }
else if str[t] == "[" {
let startIndex = t + extendedSymbols
while str[t] != "]" {
t += 1
}
t += 1
let endIndex = t + extendedSymbols
mutableString.addAttribute(
NSForegroundColorAttributeName,
value: UIColor.redColor(),
range: NSMakeRange(startIndex, endIndex - startIndex))
}
t += 1
}
Thank you all for help!!!

Selecting a tuple index using a variable in Swift

That is what i am trying to do:
var i = 0
var string = "abcdef"
for value in string
{
value.[Put value of variable i here] = "a"
i++
}
How can i insert the value of i in the code?
Easiest is probably just convert it to an NSMutableString:
let string = "abcdef".mutableCopy() as NSMutableString
println( "\(string)")
for var i = 0; i < string.length; ++i {
string.replaceCharactersInRange(NSMakeRange(i, 1), withString: "a")
}
println( "\(string)")
Yes, it's a bit ugly but it works.
A much cleaner way is to use Swifts map function:
var string = "abcdef"
let result = map(string) { (c) -> Character in
"a"
}
println("\(result)") // aaaaaa
You should just be able to use the following but this doesn't compile:
map(string) { "a" }
In you comments you mention you want to split up the string on a space, you can just use this for that:
let stringWithSpace = "abcdef 012345"
let splitString = stringWithSpace.componentsSeparatedByString(" ")
println("\(splitString[0])") // abcdef
println("\(splitString[1])") // 012345

Resources