String Operations In F#

In previous posts we learned and got familiar with the theory and code of Functional programming language F#. The last post was mostly used operation of any language“The Print”. In this post we’ll use the mostly used type and literals in code i.e. String.

String is an immutable data type in C# and F# is all about immutability. So you will not see much different between the C# string and F# string type. Means you’re already familiar with escape sequences\ verbatim strings. Below is the list of supported escape sequences in F#:

Character Escape sequence
Backspace \b
Newline \n
Carriage return\r
Tab \t
Backslash \\
Quotation mark \"
Apostrophe \'
Unicode character \uXXXX or \UXXXXXXXX (where X indicates a hexadecimal digit)

The Verbatim string

Like in C# the verbatim string is ignore special character i.e. escape sequences. In F# it works with same symbol @ and special triple-quoted string.

  1. // Using a verbatim string to represent xml node in string  
  2. let xmlFragment1 = @"<book author=""Milton, John"" title=""Paradise Lost"">"  
  3.   
  4. // Using a triple-quoted string  
  5. let xmlFragment2 = """<book author="Milton, John" title="Paradise Lost">"""  
Linebreaks

Consider below examples,
  1. let str1 = "Hello  
  2. sir"  
  3. let str2 = "Hello, \  
  4. Mam" 
The first Str1 is a string with new line character “Hello \n sir”. Linebreaks actually produces the new line character in a string spanning across lines.

Str2 is a continuous string “Hello, Mam”. When a ‘\’ backslash character is the last character before the line breaks leading whitespaces are ignored and no line breaks will be considered.

String is array* of characters

Means you can access individual character with index like in an array*.
  1. printfn"%c" str1.[1]  
*The Array in F# will be covered in a dedicated post later.

Substrings

The substring can be extracted from any string by supplying range in Index operator.
  1. printfn"%s" (str1.[0..2])// Substring from index 0 to 2  
  2. printfn"%s" (str2.[3..5])// Substring from index 3 to 5  
String as ByteArray (Ascii string)
  1. // "abc" interpreted as a Unicode string.  
  2. let str1 : string = "abc"  
  3. // "abc" interpreted as an ASCII byte array.   
  4. letbytearray : byte[] = "abc"B  
String operator

Just like C#, the ‘+’ operator concatenates two strings.  
  1. let string1 = "Hello, " + "world"  
String Formatter

In the previous post we learned about the format specifiers. The all format specifiers can be used for string formatting. The equivalent of ‘String.Format’ in F# is ‘sprintf’,
  1. letformattedString = sprintf"The first letter of alphabet in %s is %c""english"'a'  
Let’s run in F# interactive,
  1. >formattedString;;  
  2. val it : string = "The first letter of alphabet in english is a"  
The above are the basics of strings type in F#. Now let’s move to the interesting topic i.e. manipulation of strings. The string function are defined as module ‘Core.String’ under FSharp.Core namespace.

String Manipulation

The list of function is available at above mentioned MSDN link. But here we’ll try to play a little with those function to understand what those functions actually do.

collect : (char -> string) -> string -> string
concat : string ->seq<string> -> string
exists : (char -> bool) -> string -> bool
forall : (char -> bool) -> string -> bool
init : int -> (int -> string) -> string
iter : (char -> unit) -> string -> unit
iteri : (int -> char -> unit) -> string -> unit
length : string ->int
map : (char -> char) -> string -> string
mapi : (int -> char -> char) -> string -> string
replicate : int -> string -> string

collect

Builds a new string whose characters are the results of applying a specified function to each of the characters of the input string and concatenating the resulting strings.
  1. letcollectTestinginputS =  
  2. String.collect (fun c ->sprintf"%c# " c) inputS  
  3.   
  4. printfn"%s" (collectTesting"CFJ")  
Output

C# F# J#

concat

Returns a new string made by concatenating the given strings with a separator.
  1. letarr = [| "Sunday""Monday""Tuesday"; |]  
  2.   
  3. letconcatPlay = String.concat" comes after "arr  
Output:

valconcatPlay : string = "Sunday comes after Monday comes after Tuesday"

exists

Tests if any character of the string satisfies the given predicate.
  1. letcontainsUppercase string1 =  
  2. if (String.exists (fun c ->System.Char.IsUpper(c)) string1) then  
  3. printfn"The string \"%s\" contains uppercase characters." string1  
  4. else  
  5. printfn"The string \"%s\" does not contain uppercase characters." string1  
  6. containsUppercase"Hello World!"  
  7. containsUppercase"no"  
Output:

The string "Hello World!" contains uppercase characters.
The string "no" does not contain uppercase characters.

forall
  1. letisValidName string1 =  
  2. if (String.forall (fun c ->System.Char.IsLetter(c)) string1) then  
  3. printfn"The string \"%s\" is a valid name." string1  
  4. else  
  5. printfn"The string \"%s\" is not a valid name." string1  
  6. isValidName"Amit"  
  7. isValidName"Amit25"  
Output:

The string "Amit" is a valid name.
The string "Amit25" is not a valid name.

Init

Creates a new string whose characters are the results of applying a specified function to each index and concatenating the resulting strings.
  1. let string1 = String.init 10 (funi ->i.ToString())  
  2. printfn"%s" string1  
  3. let string2 = String.init 26 (funi ->  
  4. sprintf"%c" (char (i + int'A')))  
  5. printfn"%s" string2  
Output:

0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ

iter

Applies a specified function to each character in a string.
  1. letprintCharacterssourceString =   
  2. String.iter(fun c ->printfn"%c" c) sourceString  
  3. printCharacters "Happy New Year!!"  

Output

H
a
p
p
y

N
e
w

Y
e
a
r
!
!

Similarly there are below functions which takes lambda expressions(anonymous function) and applies on each character of given input.

map:

Creates a new string whose characters are the results of applying a specified function to each of the characters of the input string.

iteri and mapi

iteri function applies a specified function to the index of each character in the string and the character itself and returns unit.

mapi function creates a new string whose characters are the results of applying a specified function to each character and index of the input string.

e.g.

  1. letenumerateCharactersinputString =   
  2. String.iteri (funi c ->printfn"%d %c"i c) inputString  
  3. enumerateCharacters"TIME"  
  4. enumerateCharacters"SPACE" 
Output:

Index Unit

0 T
1 I
2 M
3 E

0 S
1 P
2 A
3 C
4 E

replicate

Returns a string by concatenating a specified number of instances of a string. 
  1. printfn"%s"<| String.replicate 10 "<>"  
Output:

<><><><><><><><><><>

length

Returns the length of the string.

The sample included with each string library function are simplified as it’s a beginner level post. In upcoming posts we’ll see more complex examples with function piping, pattern matching etc.
 
Read more articles on F#:


Similar Articles