Словарь Map

Последнее обновление: 14.12.2023

Тип Map в языке F# представляет словарь, где каждый элемент имеет ключ и связанное с ним значение.

Для определения словаря применяются квадратные скобки [], в которых располагаются элементы словаря:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]

Здесь определен словарь, который называется dict. Чтобы указать, что создается словарь, перед квадратными скобками указывается название типа - Map

Каждый элемент словаря определяется в виде:

ключ, значение

То есть сначала идет ключ и через запятую значение. Например, первый элемент словаря:

"red", "красный"

Здесь ключом выступает строка "red", а значением - строка "красный".

Если элементы размещаются на одной строке, то они отделяется друг от друга точкой с запятой. Если элементы размещены по отдельности на разных строках, тогда не требуется разделять их точкой с запятой:

let dict = Map[
    "red", "красный"
    "blue", "синий"
    "green", "зеленый"
]

По умолчанию тип элементов словаря выводится из значений, которыми инициализируется словарь. Но также можно указать тип словаря явным образом:

let dict: Map<string, string> = Map[]     // Map<тип_ключей, тип_значений>

В угловых скобках после названия типа Map указываем тип ключей и тип значений элементов. То есть в данном случае тип ключей - string и тип значений тоже string.

Явное указание типа может быть полезно, когда надо создать пустой словарь, соответственно компилятор не сможет неявно вывести тип ключей и значений.

Другой пример:

let letters: Map<string, int> = Map["a", 1; "b", 2; "c", 3]

Здесь словарь letters с качестве типа ключей использует тип string, а в качестве типа значений - int

Свойства словарей

Тип Map определяет ряд свойств:

  • Count: количество элементов в словаре

  • Keys: возвращает список ключей словаря

  • Values: возвращает список значений словаря

  • IsEmpty: возвращает true, если в словаре нет элементов

Применение свойств:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]
printfn "Count: %d" dict.Count          // Count: 3
printfn "IsEmpty: %b" dict.IsEmpty      // IsEmpty: false
printfn "Keys: %A" dict.Keys            // Keys: seq ["blue"; "green"; "red"]
printfn "Values: %A" dict.Values        // Values: seq ["синий"; "зеленый"; "красный"]

Получение элементов

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

словарь[ключ]

После имени словаря в квадратных скобках указывается ключ. Например:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]
printfn "red: %s" dict["red"]   // red: красный

Однако этот способ имеет недостаток: если переданного ключа нет в словаре, то генерируется исключение. В этом случае можно использовать метод TryFind. Он принимает ключ и возвращает значение по этому ключу Поскольку такого ключа может и не быть в словаре, то возвращается в реальности не сам элемент, а его обертка в виде объекта Option. С помощью свойства Value можно получить значение.

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]

let printOption option =
    match option with 
    | Some value -> printfn $"{value}"
    | None -> printfn "Не найдено"

let result1 = dict.TryFind  "red"
printOption result1     // красный

let result2 = dict.TryFind  "yellow"
printOption result2     // Не найдено

В первом случае ищем в словаре значение по ключу "red", а во втором случае - по ключу "yellow". Для вывода результата определяем функцию printOption, которая получает объект Option и с помощью конструкции match сопоставляет его с двумя паттернами - Some и None. Если элемент найден, тогда объект option успешно сопоставляется с Some, а его значение помещается в переменную value:

match option with 
    | Some value -> printfn $"{value}"

Аналогично работает функция Map.tryFind:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]

let printOption option =
    match option with 
    | Some value -> printfn $"{value}"
    | None -> printfn "Не найдено"

let result1 = Map.tryFind "red" dict
printOption result1     // красный

let result2 = Map.tryFind  "yellow" dict
printOption result2     // Не найдено

Перебор словаря

Для перебора элементов словаря можно использовать цикл for..in:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]
for word in dict do 
    printfn "%s: %s" word.Key word.Value 

При переборе словаря мы получаем объект, у которого с помощью свойства Key можно получить ключ, а с помощью свойства Value - значение.

Также для перебора можно использовать функцию Map.iter. Эта функция принимает два параметра. Первый параметр - функция, которая выполняется для каждого элемента словаря. Второй параметр - сам перебираемый словарь:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]
Map.iter (fun key value -> printfn "Перевод слова %s: %s" key value) dict

В функцию Map.iter передается функция, которая через два параметра получает ключ и значение каждого элемента словаря.

Фильтрация словаря

С помощью функции Array.filter можно отфильтровать элементы словаря в сответствии с некоторым условием. Функция возвращает новый словарь, которая содержит только те элементы, которые соответствуют этому условию.

Первый параметр функции - функция условия, а второй параметр - фильтруемый словарь

let people = [|"Tom"; "Alice"; "Sam"; "Kate"; "Bob"|]

let result = Array.filter (fun (p:string) ->  p.Length = 3) people
printfn "%A" people     // [|"Tom"; "Sam"; "Bob"|]

В данном случае получаем в новый словарь из исходного словаря все строки, длина которых равна 3 символам.

Проверка наличия элементов

Метод ContainsKey() позволяет проверить, есть ли в словаре элемент с определенным ключом. При наличии такого элемента возвращается true, иначе возвращается false:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]

printfn "Есть ли слово `red`: %b" (dict.ContainsKey "red")
printfn "Есть ли слово `yellow`: %b" (dict.ContainsKey "yellow")

Изменение словаря

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

Добавление в словарь

Метод Add() возвращает копию словаря, в которую добавляется новый элемент. Данному методу передается кортеж, первое значение в котором представляет ключ, а второе - значение:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]
let newDict = dict.Add ("yellow", "желтый")

printfn "%A" newDict
// консольный вывод
// map [("blue", "синий"); ("green", "зеленый"); ("red", "красный"); ("yellow", "желтый")]

Аналогично работает функция Map.add:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]
let newDict = Map.add "yellow" "желтый" dict

Удаление из словаря

Метод Remove() возвращает копию словаря, из которой удаляется элемент с определенным ключом:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]
let newDict = dict.Remove "blue"

printfn "%A" newDict
// консольный вывод
// map [("green", "зеленый"); ("red", "красный")]

Аналогично работает функция Map.remove:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]
let newDict = Map.remove "blue" dict

Изменение элемента в словаре

Метод Change() возвращает копию словаря, в которой изменен элемент с определенным ключом:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]

let newDict = dict.Change ("red", (fun item ->
    match item with
     | Some -> Some ("алый")
     | None -> None
))
printfn "%A" newDict
// консольный вывод
// map [("blue", "синий"); ("green", "зеленый"); ("red", "алый")]

Метод Change() получает кортеж, в котором первое значение - ключ изменяемого элемента, а второе значение - функция изменения. Поскольку запрошенного ключа, по которому мы хотим изменить значение, может не оказаться, то в эту функцию передается объект Option. Если ключ есть в словаре, то его можно получить через значение Some и также через Some можно установить новое значение. В данном случае меняем для ключа "red" значение на "алый"

Аналогично работает функция Map.change:

let dict = Map["red", "красный"; "blue", "синий"; "green", "зеленый"]

let newDict = dict |> Map.change "red" (fun item ->
    match item with
     | Some s -> Some ("алый")
     | None -> None)

printfn "%A" newDict
// консольный вывод
// map [("blue", "синий"); ("green", "зеленый"); ("red", "алый")]
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850