Перейти к содержанию

Программирование на языке Scala/Кортеж

Материал из Викиверситета

Кортеж (tuple) объединяет фиксированное количество элементов разных типов, позволяя выполнять их передачу в виде единого целого. Кортеж можно назвать анонимной простой структурой данных, предназначенной как правило, для передачи данных между выражениями, когда требуется скомпоновать разнородные данные, не создавая при этом более сложных структур.

Пример кортежа:

(1, "s", 3L, 'a')

При этом тип кортежа:

(Int, String, Long, Char)

Кортеж сильно напоминает список параметров функции, но не является таковым, так как имеет другое предназначение. Кортеж это выражение, имеющей значение и тип. Экземпляру кортежа можно присвоить имя:

val tuple4 = (1, "s", 2L, 'a')

Количество элементов кортежа может быть от 1 до 22. Кортеж с двумя элементами может быть задан двумя способами:

(1, "s")
// или
1 -> "s"

Доступ к элементам кортежа выполняется следующим образом:

val tuple4 = (1, "s", 2L, 'a')
val int = tuple4._1
val str = tuple4._2
val long = tuple4._3
val char = tuple4._4

Довольно часто кортежи применяются для возвращения из функции нескольких значений.

val fun: Int => (Int, String, Long, Char) = 
    int: Int => {
        val str = int.toString
        val long = int.toLong
        val char = int.toChar
        (int, str, long, char)
    }
//Или краткая форма
val fun2: Int => (Int, String, Long, Char) = int => (int, int.toString, int.toLong, int.toChar)
//Вызов функции
val tuple4: (Int, String, Long, Char) = fun(1)

При получении кортежа из функции, можно сразу разложить его на именованные элементы:

val fun: Int => (Int, String, Long, Char) = int => (int, int.toString, int.toLong, int.toChar)
val (int, string, long, _) = fun(1)
println(int)
println(string)
println(long)

Символ _ в перечне названий элементов указывает на то, что последний элемент кортежа не нужен.


Кортежи - отличный способ быстро сгруппировать данные, но они недостаточно выразительны. Элементы в кортеже не имеют имен. Основное назначение кортежей, это временная группировка данных.

Каждый раз, когда вы используете кортежи в качестве возвращаемых типов функции, особенно если кортеж содержит три или более элементов, вам следует спросить себя: не выполняет ли эта функция слишком много вычислений?

Домашнее задание[править]

1. В учебном проекте создать файл Tuples.sc (Scala-Worksheet)

2. Реализовать функцию splitFun, которая делит строку на две части по указанному символу разделителю, и возвращает кортеж из двух строк. Разделитель в возвращаемые строки не входит. Можно использовать takeWhile и dropWhile

Заготовка реализации:

val splitFun: (String, Char) => (String, String) =
  (str, char) => {
    ??? // Реализация тут
  }

splitFun("abcd", 'c') // Результат (ab,d)

3. Реализовать аналог метода tail. Использовать foldLeft

Заготовка реализации:

val tailFun: String => String =
  str =>
    str.foldLeft(("", true))( (acc, el) => {
      val (res, isHead) = acc
      ??? // Реализация тут
    })._1

tailFun("abc") // Результат bc

4. Реализовать аналог метода take. Использовать foldLeft

Заготовка реализации:

val takeFun: (String, Int) => String =
  (str, num) =>
    str.foldLeft(("", 0))((acc, el) => {
      ??? // Реализация тут
    })._1

takeFun("abc", 2) // Результат ab

5. Реализовать аналог метода drop. Использовать foldLeft

Заготовка реализации:

val dropFun: (String, Int) => String =
  ??? // Реализация тут

dropFun("abc", 2) // Результат c

6. Реализовать аналог метода init. Использовать foldLeft

Заготовка реализации:

val initFun: String => String =
  ??? // Реализация тут

initFun("ab") // Результат a

7. Реализовать аналог метода indexOf. Использовать foldLeft

Заготовка реализации:

val indexOfFun: (String, String) => Int =
  (str, pattern) => {
    val res = str.foldLeft((0, 0, false))( (acc, el) => {
      val (strIndex, patternIndex, isSuccess) = acc
      ??? // Реализация тут
  }

println("Проверка 3", "Результат: " + indexOfFun("abcd", "b") + " Нужно: 1")
println("Проверка 4", "Результат: " + indexOfFun("abcd", "c") + " Нужно: 2")
println("Проверка 5", "Результат: " + indexOfFun("abcd", "a") + " Нужно: 0")
println("Проверка 6", "Результат: " + indexOfFun("abcd", "") + " Нужно: -1")
println("Проверка 7", "Результат: " + indexOfFun("", "bc") + " Нужно: -1")
println("Проверка 8", "Результат: " + indexOfFun("abcd", "e") + " Нужно: -1")
println("Проверка 9", "Результат: " + indexOfFun("abcd", "bc") + " Нужно: 1")
println("Проверка 10", "Результат: " + indexOfFun("abcd", "") + " Нужно: -1")
println("Проверка 11", "Результат: " + indexOfFun("", "ec") + " Нужно: -1")
println("Проверка 12", "Результат: " + indexOfFun("", "") + " Нужно: -1")
println("Проверка 13", "Результат: " + indexOfFun("a", "abc") + " Нужно: -1")
println("Проверка 14", "Результат: " + indexOfFun("abc", "abc") + " Нужно: 0")
println("Проверка 15", "Результат: " + indexOfFun("abc", "ac") + " Нужно: -1")
println("Проверка 16", "Результат: " + indexOfFun("abc", "ff") + " Нужно: -1")
println("Проверка 17", "Результат: " + indexOfFun("abcd", "ca") + " Нужно: -1")
println("Проверка 18", "Результат: " + indexOfFun("abedabcd", "bc") + " Нужно: 5")

Ответы на домашнее задание[править]