# Calculation Writing Tutorial - 6.  Working with Strings

Version 5

### Verified Product Versions

Service Desk 7.7.xService Desk 7.8.x

### Introduction

This document is the sixth in a set of tutorials on writing calculations in Service Desk.  Each topic can be read independently but for an introduction to calculations please see the following document: Calculation Writing Tutorial - 1. What is a calculation? What is Boo?.

#### Intended Audience

Some experience in object and process design is recommended, as well as the basic concept of calculations as covered in the first tutorial (linked above) and also tutorial number 5: Calculation Writing Tutorial - 5.  Boo language features versus .NET classes.

#### What are Strings?

A "String" is basically a piece of text.  In Service Desk you should already be familiar with the concept if you have done any design work and created or worked with String attributes on business objects.  In calculations you can use Strings in various ways using features built in to Boo and Methods in the System.String class of the .NET Framework.

When typing a String in a calculation it needs to be in quote marks otherwise Boo will think you are trying to refer to a variable or attribute with that name.  You can use either single or double quotes as long as you are consistent.

### Working with Strings using functionality in the Boo language

There are two simple tasks you can perform with Strings using nothing but Boo functionality.

#### String Concatenation

To combine multiple Strings you simply "add" them together:

```Value1 = 'This is the start of'
Value2 = ' the rest of this sentence'
Value3 = Value1 + Value2
```

In the above example the variable Value3 is set to the two other variables combined: "This is the start of the rest of this sentence".  You can also append an existing String variable using the += symbol:

```Value = 'This is the start of'
Value += ' the rest of this sentence'
```

You can combine more than two Strings at a time and they don't have to be existing variables or attributes:

```Value1 = 'Hello'
Value2 = 'How are you'
Value3 = Value1 + ' ' + Incident.RaiseUser.Title + '. ' + Value2 + '?'
```

For more complex manipulation, plus a tidier way to achieve the above, you must use .NET Methods which are described in the next section.

#### Comparing a String

Within an "if" statement you can compare two Strings.  With Boo alone you can only make a direct comparison to check if the Strings are identical.  This is done as follows:

```if Incident.RaiseUser.Title == 'Stu': ....
```

This compares the Raise User's Title attribute with the text "Stu".  Note that this check is case sensitive so values such as "stu" or "STU" would not match.  For more complex comparisons you must use .NET Methods.

#### Using apostrophes and quote symbols in Strings

You can use either single or double quotes to surround a String:

```Value = 'This uses single quotes'
Value = "This now uses double quotes"
```

If you need to include a ' or " character as part of the text then this needs to be dealt with.  The following examples would both result in syntax errors:

```Value = 'This hasn't handled the apostrophe!'
Value = "I said "This will not work"."
```

You can handle these situations in one of two ways.  Firstly you can switch between which character is used to surround the text:

```Value = "This will work now I'm sure"
Value = 'And then I said "This will work now".'
```

Alternatively you can "escape" the characters by prefixing them with a blackslash:

```Value = 'This won\'t actually display the backslash before the apostrophe'
Value = "And finally I said \"This is valid now thanks to the backslashes\"."
```

### .NET Methods for working with Strings

A full list of Methods for the String class see the following MSDN document:  http://msdn.microsoft.com/en-us/library/system.string.  That list can be daunting so this document will cover some of the more common items.  The methods can be grouped into two different types: manipulating a String and Getting information on a String.  An important point to make before going any further is that with all of the following examples the Method returns the manipulated value but does not alter the original variable or attribute in any way.

#### Methods for manipulating a String

The following Methods will help if you need to use a String in a modified form:

##### Getting a portion of a String using SubString()

The .Substring() Method is used to return a portion of a String.  You specify a Start Index and optionally a Length.  Start Index is the number of characters from the start to skip:

```Value = 'This is a String'
CharSixOnwards = Value.Substring(5)
JustCharNine = Value.Substring(8,1)
```

In the above examples the variable CharSixOnwards is set to "is a String".  The 5 used as its parameter tells it to skip the first 5 characters ('This ').  The variable JustCharNine is set to "a".  The first parameter tells it to skip the first 8 characters and the second parameter tells it to return 1 character from that point onwards.

##### Replacing or removing some text in a String using Replace()

The .Replace() method is used to replace some text within a String with new text:

```Lie = 'I hate Back To The Future'
Truth = Lie.Replace('hate', 'love')
```

In the above example the variable Truth is set to "I love Back To The Future".  Note that the variable Lie is still set to 'I hate Back To The Future'.

There is no Method for removing text without knowing where in the String it appears however you can use .Replace() for this:

```Lie = 'I am definitely not obsessed with Back To The Future'
Truth = Lie.Replace('not ', '')
```

In the above example the variable Truth is set to "I am definitely obsessed with Back To The Future".

##### Changing the Case of a String using ToUpper() and ToLower()

If you want to convert all the text in a String to upper or lower case this is very easy:

```MyString = 'This is MiXeD CaSe'
MyLowerCaseString = MyString.ToLower()
MyUpperCaseString = MyString.ToUpper()
```

The variable MyLowerCaseString is set to "this is mixed case" while MyUpperCaseString is set to "THIS IS MIXED CASE".

##### String Concatenation using String.Format()

Earlier in this document you saw how easy it is to combine multiple Strings using Boo functionality alone.  There is however a best practice way to do this which is easier to read and adds more flexibility:

```Value1 = 'Hello'
Value2 = 'How are you'
Value3 = String.Format('{0} {1}. {2}?', Value1, Incident.RaiseUser.Title, Value2)
```

The String.Format() Method is Static, meaning you are not running it against any existing String.  It takes at least two parameters but can take as many as you need to account for each variable or attribute you want to combine.  The first variable is a String that acts as a template containing placeholders that get replaced by all other parameters.  The placeholders are encased in { }, numbered starting from zero and refer to the other parameters in the order you specify them.

In the above example if Value1 and Value2 aren't ever going to change the String.Format() could instead include those pieces of text as part of the template:

```Value = String.Format('Hello {0}.  How are you?', Incident.RaiseUser.Title)
```

#### Methods for getting information from a String

The methods in the previous section manipulated the String.  The following methods return a Boolean or Int32 value to give you information on a String.

##### Advanced String Comparison using ContainsI(), IsNullofEmpty(), StartsWith() and EndsWith()

The following are generally used as part of "if" statements to tell you if something about a String is true or false:

```if Incident.RaiseUser.Title.Contains('Stu'): ...

if String.IsNullorEmpty(Incident.Description): ...

MyLastName = 'McNeill'
if Incident.RaiseUser.Title.EndsWith(MyLastName): ...
```

The above examples are fairly self explanatory.  Each of these Methods returns a Boolean value and can be used as the only clause of an "if" statement.  In the case of .StartsWith() the example converts the String to lower case first which demonstrates how Methods can be chained together.  In the case of .EndsWith() the parameter used is a variable which demonstrates that the parameter does not need to be hard-coded.

##### Finding the position of text in a String using IndexOf() and LastIndexOf()

The following Method tells you the position a piece of text appears in a String:

```Value = 'This is some text with some words and some more words.'
PositionOfSome = Value.IndexOf('some')
```

In the above example the variable PositionOfSome is set to 8 which is the number of characters to skip to get to the start of the String given in the Method's parameter ("some").  If the text was not found the return value would be -1.

The word "some" appears multiple times in the String but this found us the first instance.  If you wanted to find the 2nd instance you can specify a second parameter with a position to start searching from:

```Value = 'This is some text with some words and some more words.'
PositionOfSome = Value.IndexOf('some')
PositionOfSecondSome = Value.IndexOf('some', PositionOfSome + 1)
```

The above example finds the first instance position, then uses that value plus 1 as the start position to find the second instance.  The variable PositionOfSecondSome is set to 23.  If you want to find the last instance of a piece of text there is a dedicated Method for this:

```Value = 'This is some text with some words and some more words.'
PositionOfLastSome = Value.LastIndexOf('some')
```

In the above example the variable PositionOfLastSome is set to 38.

The .IndexOf() and .LastIndexOf() Methods are especially useful as parameters for the .Substring() method explained earlier in this document:

```Value = 'This is some text with some words and some more words.'
WordsOnwards = Value.Substring( Value.IndexOf('words') )
```

In the above example the variable WordsOnwards is set to "words and some more words".  The .IndexOf() Method is used to find the position of the first instance of "words" and the returning value (28) is used as the parameter for the .Substring() Method to return a portion of the original value from that position onwards.