Причина возврата Map.unzip в Scala (Iterable, Iterable)

На днях мне стало интересно, почему scala.collection.Map определяет метод распаковки как

def unzip [A1, A2] (implicit asPair: ((A, B)) ⇒ (A1, A2)): (Iterable[A1], Iterable[A2])

Поскольку метод возвращает "только" пару Iterable вместо пары Seq, не гарантируется, что пары ключ / значение в исходной карте встречаются при совпадении индексов в возвращаемых последовательностях, поскольку Iterable не гарантирует порядок обхода. Так что, если бы у меня был

Map((1,A), (2,B))

потом после звонка

Map((1,A), (2,B)) unzip

Я мог бы в конечном итоге

... = (List(1, 2),List(A, B))

так же, как и с

... = (List(2, 1),List(A, B))

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

Может быть, такое поведение должно быть более четко выражено в прилагаемом скаладоке?

РЕДАКТИРОВАТЬ: Обратите внимание, что я не имею в виду карты как упорядоченные коллекции. Меня интересуют только "совпадающие" последовательности после распаковки, т.е. для

val (keys, values) = someMap.unzip

для всех i верно, что (keys(i), values ​​(i)) является элементом исходного отображения.

4 ответа

Решение

На самом деле приведенных вами примеров не будет. Map всегда будет расстегнут молнией попарно. Ваше заявление о том, что Iterable не гарантирует порядок, не совсем верно. Точнее сказать, что любой данный Iterable не должен гарантировать порядок, но это зависит от реализации. В случае Map.unzipупорядочение пар не гарантируется, но элементы в парах не изменятся так, как они сопоставляются - это соответствие является фундаментальным свойством Map, Вы можете прочитать источник GenericTraversableTemplate чтобы убедиться, что это так.

Если вы расширите unzipОписание, вы получите ответ:

definition classes: GenericTraversableTemplate

Другими словами, он не стал специализированным для Map,

Тем не менее, ваш аргумент обоснован, и, полагаю, вы могли бы получить ваши пожелания, если откроете билет улучшения с помощью своих рассуждений. Особенно, если вы захотите выпустить патч, если не больше, по крайней мере, вы узнаете намного больше о коллекциях Scala.

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

(Однако я затрудняюсь объяснить, почему карта имеет zipWithIndex метод. Это дает контраргумент в мою точку зрения. Я предполагаю, что он существует для согласованности с другими коллекциями и что, хотя он и обеспечивает индексы, они не гарантируются такими же при последующих вызовах.)

Если вы используете LinkedHashMap или LinkedHashSet, итераторы должны возвращать пары в исходном порядке вставки. Другие HashMaps, да, у вас нет контроля. Сохранение исходного порядка вставки весьма полезно в контексте пользовательского интерфейса, оно позволяет вам преобразовывать таблицы в любом столбце веб-приложения, например, без изменения типов.

Другие вопросы по тегам