Почему группа Clojure не всегда поддерживает порядок? - PullRequest
7 голосов
/ 06 февраля 2012

Почему (групповая идентификация (диапазон 1 50)) возвращает результаты типа

{32 [32], 1 [1], 33 [33], 2 [2], 34 [34], 3 [3], 35 [35] ...

Это связано с многопоточностью? Есть ли способ обойти это?

... а это нарушает контракт?

Возвращает карту элементов coll, полученных по результату f для каждого элемента. Значением каждого ключа будет вектор соответствующих элементов, в том порядке, в котором они указаны в coll .

1 Ответ

14 голосов
/ 06 февраля 2012

Попробуйте ввести (type (group-by identity (range 1 50))) в своем REPL.Вы можете видеть, что результатом является фактически хеш-карта (класса clojure.lang.PersistentHashMap).Это означает, что он неупорядочен: в принципе REPL может выводить печатный литерал карты в любом порядке пар ключ / значение.

Фактическая причина, по которой он печатается так, как печатается, связана с реализацией хешем Clojuremap - с точки зрения структур данных, это на самом деле широкое дерево, в котором каждый узел может иметь до 32 дочерних элементов (отсюда и исходные 32 в ваших выходных данных; напомним, что векторы и карты Clojure часто цитируются, чтобы иметь стоимость поиска O (log32N)). Эта статья блога имеет хорошее резюме.

И нет, это не нарушает договор group-by.Контракт определяет только порядок элементов значений карты, а не порядок карты как таковой .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...