Omap — это пакет Golang для работы с потокобезопасными упорядоченными map. Упорядоченная map содержит map golang, list и mutex для выполнения функций упорядоченной map.

Упорядоченная map— это map, которая запоминает порядок элементов. Map можно итерировать для извлечения элементов в том порядке, в котором они были добавлены.

Введение в пакет omap Go

Пакет omap Go — это легкая и эффективная библиотека для работы с упорядоченными map в Go. Упорядоченная map— это структура данных, которая объединяет преимущества map и list, позволяя хранить пары ключ-значение в определенном порядке.

Что такое omap?

Omap — это пакет Go, который обеспечивает реализацию упорядоченной map. Он разработан для быстрого, эффективного и простого использования. Omap особенно полезен, когда вам нужно хранить данные в определенном порядке, например, при работе с файлами конфигурации, кэшированием или конвейерами обработки данных.

Основные характеристики omap

Упорядоченность: omap сохраняет порядок вставки пар ключ-значение, что позволяет вам выполнять итерацию по map в определенном порядке.

Быстрые поиски: omap использует хэш-таблицу для хранения пар ключ-значение, что делает поиск быстрым и эффективным.

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

Использование omap

Чтобы использовать omap, вы можете установить его с помощью следующей команды:

go get github.com/kirill-scherba/omap

Вот пример использования omap:

package main

import (
    "fmt"
    "log"

    "github.com/kirill-scherba/omap"
)

func main() {
    // Create a new ordered map
    m, err := omap.New[string, string]()
    if err != nil {
        log.Fatal(err)
    }

    // Insert some key-value pairs
    m.Set("key1", "value1")
    m.Set("key2", "value2")
    m.Set("key3", "value3")

    // Iterate over the omap in order
    for _, pair := range m.Pairs() {
        fmt.Printf("%s: %s\n", pair.Key, pair.Value)
    }
}

Этот код создает новый omap объект, вставляет несколько пар ключ-значение, а затем выполняет итерацию по omap по порядку, выводя каждую пару ключ-значение.

Посмотрите и выполните этот пример на Go Playground: https://go.dev/play/p/LzauNwMuezB

Заключение

Пакет omap Go — полезная библиотека для работы с упорядоченными map в Go. Его быстрый поиск, эффективная вставка и удаление, а также упорядоченная итерация делают его отличным выбором для различных вариантов использования. Независимо от того, работаете ли вы с файлами конфигурации, кэшированием или конвейерами обработки данных, omap определенно стоит рассмотреть.

Примеры вариантов использования

  • Файлы конфигурации: используйте omap для хранения данных конфигурации в определенном порядке, что упрощает итерацию по конфигурации и применение настроек в правильном порядке.

  • Кэширование: используйте omap для хранения кэшированных данных в определенном порядке, что упрощает итерацию по кэшу и удаление элементов в правильном порядке.

  • Конвейеры обработки данных: используйте omap для хранения данных в определенном порядке, что упрощает итерацию по данным и их обработку в правильном порядке.

Подробное описание и примеры смотрите на странице проектов omap на github

Документация

Комментарии (12)


  1. wataru
    15.02.2025 12:50

    Упорядоченная map— это map, которая запоминает порядок элементов. Map можно итерировать для извлечения элементов в том порядке, в котором они были добавлены.

    Точно так? А не в порядке возрастания ключей, как это во всех других известных мне языках программирования?


    1. ZyXI
      15.02.2025 12:50

      Это где так? Обычно итерация происходит в одном из двух порядков:

      1. В порядке добавления ключей.

      2. В неопределённом порядке, оно же в порядке, в каком данные располагаются в map (т.е. по сути что‐то вроде «в порядке возрастания остатков от деления хэшей на размер map», если не учитывать коллизий).

      Оба порядка — это «в каком порядке удобно делать итерацию при данной реализации map», и «в порядке возрастания ключей» удобно делать, только если map — это дерево вроде BTreeMap, а не хэш‐таблица.

      Помимо этого есть lua, где таблицы одновременно ещё и массивы и другие языки со схожими идеями, где, в зависимости от ключа, значение окажется либо во внутреннем массиве, либо в хэш‐таблице, но даже у lua порядок никак не гарантируется даже для числовых индексов (вероятно, т.к. вы вполне можете засунуть числовой индекс в хэш‐таблицу, а не в массив).


      1. tolyanski
        15.02.2025 12:50

        https://en.cppreference.com/w/cpp/container/map

        вот тут например ключи сортируются а не хранятся в порядке добавления. Но это там названо просто map, в то же время в плюсах есть unordered map, где порядок добавления не запоминается.

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

        Так например названо в C#, где OrderedDictionary запоминает порядок добавления ключей, а SortedDictionary - сортирует их


        1. wataru
          15.02.2025 12:50

          По ссылке же:

          Keys are sorted by using the comparison function Compare

          Не в порядке добавления. А в порядке возрастания ключей в C++.

          В C# я думал как раз про SortedDictionary. Все-таки по ключам. В Жаве тоже есть SortedMap, Тоже по ключам.


          1. tolyanski
            15.02.2025 12:50

            Кажется вы не поняли мое предложение про плюсы. У меня написано так:

            вот тут например ключи сортируются а не хранятся в порядке добавления


          1. ZyXI
            15.02.2025 12:50

            В C# Dictionary без Sorted не сортирует по ключам. Интерфейс Map в Java не требует определённого порядка. Если это более скриптовый язык, где словари являются частью основного синтаксиса, то внутри почти наверняка будет хэш‐таблица, которые с сортировкой по ключам не очень дружат.

            Собственно под «обычно» я думал скорее про них — я обычно использую Rust или такие скриптовые языки и в Rust есть, к примеру, HashMap и BTreeMap, но у обоих название вида ImplementationMap и нельзя сказать, что есть какие‐то предпочтения на уровне языка или стандартной библиотеки. HashMap, впрочем, используется чаще, потому что за сортировку по ключам вы платите скоростью всех операций в данном случае.


    1. tolyanski
      15.02.2025 12:50

      Вероятно автор подсмотрел идею в PHP, где "array", если используется как мапа, запоминает порядок элементов как их добавляли.

      Кстати, так и есть:


      1. funny_falcon
        15.02.2025 12:50

        Не только PHP. Современный Python, Ruby и (могу ошибаться) JavaScript тоже гарантируют итерацию в порядке добавления.


        1. ZyXI
          15.02.2025 12:50

          Ruby и Python — да. В javascript похоже засунули в стандарт оптимизацию, используемую для таблиц lua (скорее не саму оптимизацию, но её последствия в части того, как удобнее всего реализовывать итерацию по object): MDN в документации for..in утверждает

          The traversal order, as of modern ECMAScript specification, is well-defined and consistent across implementations. Within each component of the prototype chain, all non-negative integer keys (those that can be array indices) will be traversed first in ascending order by value, then other string keys in ascending chronological order of property creation.

          Где это написано в собственно спецификации ECMAScript я не нашёл, но в этом тексте написано сначала цифровые индексы по порядку, потом строковые ключи таки в порядке добавления.


  1. Borz
    15.02.2025 12:50

    Если уж речь зашла про map и Go версии не ниже 1.23, то почему бы сразу не использовать https://pkg.go.dev/iter ? И реализовать совместимость с https://pkg.go.dev/maps , чтобы это можно было "прозрачно" использовать с другим кодом на Go


    1. kirill-scherba Автор
      15.02.2025 12:50

      Там всё так и сделано )


  1. kirill-scherba Автор
    15.02.2025 12:50

    :-)