Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 56 additions & 14 deletions concepts/strings/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,54 @@ val s = "Escape backslash \\."
// Escape backslash \.
```

Raw strings use 3 double-quotes, and can contain arbitrary text (no need for escaping).
Multiline strings are also supported, including flexible handling of indents.
Multi-line strings are surrounded by 3 double-quotes, and can contain arbitrary text (no need for escaping).

```kotlin
val multi = """I'm a
|multi-line
|string with special characters \ \t """
multi-line
string with special characters \ \t """
//I'm a
// multi-line
// string with special characters \ \t
```

Use [trimIndent][trimIndent-doc] to remove the common indenting from the lines.
This is useful for formatting the string:

```kotlin
val multi = """
I'm a
multi-line
string""".trimIndent()

multi.trimMargin() // delimiter defaults to | but can be specified
//I'm a
//multi-line
//string with special characters \ \t
// multi-line
//string
```

Alternatively, [trimMargin][trimMargin-doc] lets you specify a delimiter.
Each line in the `String` then begins after the delimiter.
The delimiter defaults to `|`, but you can specify a different delimiter as a parameter.
For example:

```kotlin
val multi = """
|I'm a
| multi-line
|string""".trimMargin()

//I'm a
// multi-line
//string

val multi2 = """
start>I'm a
start> multi-line
start>string""".trimMargin("start>")

//I'm a
// multi-line
//string
```

Strings can be concatenated with `+`, but this is best limited to short and simple cases.
Expand Down Expand Up @@ -70,7 +106,7 @@ Mostly, these are [`extensions functions`][ref-extensions] rather than members o

~~~~exercism/note
Kotlin's rather complex [documentation][ref-string-functions] pages hide extension functions in the default view.
At moment of writing this, the most valuable content is hidden in a tab named `Members and Extensions`.
At moment of writing this, the most valuable content is hidden in a tab named `Members & Extensions`.
Click it to expand this section and see all the members and extensions available on the `String` class.

[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/
Expand All @@ -85,15 +121,19 @@ str.length // => 12 (a property, not a function)
str.elementAt(6) // => W
str.elementAtOrNull(20) // => null (index out of range)
str.substring(6, 11) // => "World"
str.substringAfter(" ") // => "World!"

str.lowercase() // => "hello world!"
str.uppercase() // => "HELLO WORLD!"

str.lowercase() // => "hello world!"
str.uppercase() // => "HELLO WORLD!"
str.startsWith("Hel") // => true
str.endsWith("xyz") // => false
str.indexOf("0") // => 4

str.startsWith("Hel") // => true
str.endsWith("xyz") // => false
str.toCharArray() // => [H, e, l, l, o, , W, o, r, l, d, !]
"42".toInt() + 1 // => 43 (parsing; see also toFloat)

str.toCharArray() // => [H, e, l, l, o, , W, o, r, l, d, !]
"42".toInt() + 1 // => 43 (parsing; see also toFloat)
"Howdy! ".trim() // => "Howdy"
```

## Building a string
Expand Down Expand Up @@ -157,3 +197,5 @@ val countDown = buildString {
[ref-sb-deleterange]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/#-1622040372%2FFunctions%2F-956074838
[ref-buildstring]: https://kotlinlang.org/docs/java-to-kotlin-idioms-strings.html#build-a-string
[ref-jointostring]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/join-to-string.html
[trimIndent-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-indent.html
[trimMargin-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-margin.html
80 changes: 61 additions & 19 deletions concepts/strings/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,63 @@ A [`string`][ref-string] in Kotlin is an immutable sequence of Unicode character

[`Unicode`][wiki-unicode] means that most of the world's writing systems can be represented, but (in contrast to older languages such as C) there is no 1:1 mapping between characters and bytes.

A string is usually surrounded by double-quotes `" "`.
A string is surrounded by double-quotes `" "`.

Some characters need escaping: `\'`, `\\`, plus the usual non-printing characters such as `\t` (tab) and `\n` (newline).
Some characters need escaping: `\\`, plus the usual non-printing characters such as `\t` (tab) and `\n` (newline).

```kotlin
val s = "Escape apostrophe \' and backslash \\."
// Escape apostrophe ' and backslash \.
val s = "Escape backslash \\."
// Escape backslash \.
```

Raw strings use 3 double-quotes, and can contain arbitrary text (no need for escaping).
Multiline strings are also supported, including flexible handling of indents.
Multi-line strings are surrounded by 3 double-quotes, and can contain arbitrary text (no need for escaping).

```kotlin
val multi = """I'm a
|multi-line
|string with special characters \ \t """
multi-line
string with special characters \ \t """
//I'm a
// multi-line
// string with special characters \ \t
```

Use [trimIndent][trimIndent-doc] to remove the common indenting from the lines.
This is useful for formatting the string:

```kotlin
val multi = """
I'm a
multi-line
string""".trimIndent()

multi.trimMargin() // delimiter defaults to | but can be specified
//I'm a
//multi-line
//string with special characters \ \t
// multi-line
//string
```

Alternatively, [trimMargin][trimMargin-doc] lets you specify a delimiter.
Each line in the `String` then begins after the delimiter.
The delimiter defaults to `|`, but you can specify a different delimiter as a parameter.
For example:

```kotlin
val multi = """
|I'm a
| multi-line
|string""".trimMargin()

//I'm a
// multi-line
//string

val multi2 = """
start>I'm a
start> multi-line
start>string""".trimMargin("start>")

//I'm a
// multi-line
//string
```

Strings can be concatenated with `+`, but this is best limited to short and simple cases.
Expand Down Expand Up @@ -56,12 +92,12 @@ Mostly, these are [`extensions functions`][ref-extensions] rather than members o

~~~~exercism/note
Kotlin's rather complex [documentation][ref-string-functions] pages hide extension functions in the default view.
Be sure to click `Members and Extensions` to expand this section.
Be sure to click `Members & Extensions` to expand this section.

[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/
~~~~

The following example shows just a small selection of what is available:
The following examples show just a small selection of what is available:

```kotlin
val str = "Hello World!"
Expand All @@ -70,15 +106,19 @@ str.length // => 12 (a property, not a function)
str.elementAt(6) // => W
str.elementAtOrNull(20) // => null (index out of range)
str.substring(6, 11) // => "World"
str.substringAfter(" ") // => "World!"

str.lowercase() // => "hello world!"
str.uppercase() // => "HELLO WORLD!"

str.lowercase() // => "hello world!"
str.uppercase() // => "HELLO WORLD!"
str.startsWith("Hel") // => true
str.endsWith("xyz") // => false
str.indexOf("0") // => 4

str.startsWith("Hel") // => true
str.endsWith("xyz") // => false
str.toCharArray() // => [H, e, l, l, o, , W, o, r, l, d, !]
"42".toInt() + 1 // => 43 (parsing; see also toFloat)

str.toCharArray() // => [H, e, l, l, o, , W, o, r, l, d, !]
"42".toInt() + 1 // => 43 (parsing; see also toFloat)
"Howdy! ".trim() // => "Howdy"
```


Expand All @@ -88,3 +128,5 @@ str.toCharArray() // => [H, e, l, l, o, , W, o, r, l, d, !]
[ref-stringbuilder]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/-string-builder/
[ref-extensions]: https://kotlinlang.org/docs/extensions.html#extensions.md
[ref-string-functions]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/
[trimIndent-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-indent.html
[trimMargin-doc]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.text/trim-margin.html
12 changes: 12 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@
"basics"
],
"status": "wip"
},
{
"slug": "log-levels",
"name": "log-levels",
"uuid": "ef54c5e6-7d31-42d1-a300-e405169dbd7f",
"concepts": [
"strings"
],
"prerequisites": [
"basics"
],
"status": "wip"
}
],
"practice": [
Expand Down
28 changes: 28 additions & 0 deletions exercises/concept/log-levels/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Hints

## General

- Kotlin provides many [functions][ref-strings] for working with Strings. Be sure to check out the `Members & Extensions` tab!

## 1. Get message from a log line

- There is a [function][ref-string-substringAfter] to extract the part of a `String` after a given delimiter.
- Removing whitespace from a `String` is explored in [Remove All Whitespaces from a String in Kotlin][tutorial-trim-white-space].

## 2. Get log level from a log line

- There is also a [function][ref-string-substringBefore] to extract part of a `String` _before_ a given delimiter.
- There is a [way][ref-string-lowercase] to change a `String` to lowercase.

## 3. Reformat a log line

- [String templates][docs-string-template] can be done with a [multiline string][docs-string-multiline].

[docs-string-multiline]: https://kotlinlang.org/docs/strings.html#multiline-strings
[docs-string-template]: https://kotlinlang.org/docs/strings.html#string-templates
[ref-strings]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/
[ref-string-indexOf]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/#-537588047%2FFunctions%2F-1430298843
[ref-string-lowercase]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/#-648004414%2FFunctions%2F-956074838
[ref-string-substringAfter]: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/#1564391517%2FFunctions%2F-1430298843
[tutorial-search-text-in-string]: https://javarevisited.blogspot.com/2016/10/how-to-check-if-string-contains-another-substring-in-java-indexof-example.html
[tutorial-trim-white-space]: https://www.baeldung.com/kotlin/string-remove-whitespace
29 changes: 29 additions & 0 deletions exercises/concept/log-levels/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Instructions

In this exercise you'll be processing log-liners.

Each log line is a string formatted as follows: "[<LEVEL>]: <MESSAGE>*".

## 1. Get the message from a log line

Implement the `LogLevels.message()` function to return the message from a log line, with the leading and trailing whitespaces removed.

## 2. Get the log level from a log line

Implement the `LogLevels.logLevel()` function to return the log level from a log line in lower case.

## 3. Reformat a log line

Implement the `LogLevels.reformat()` method that takes a log line and a location string and reformats into a message containing two lines.
The first line is formatted as `<LEVEL>@<LOCATIOON>:`, where:

* `<LEVEL>` is the log level in lower case (as from 2. Get the log level from a log line).
* `<LOCATION>` is the location given as the second parameter.

The second line contains exactly two spaces, followed by the log message (as from 1. Get the message from a log line):

```kotlin
reformat("[TRACE]: Start of function", 2, 8)
// => "trace@208:
Start of function"
```
Loading