Причина возврата 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, да, у вас нет контроля. Сохранение исходного порядка вставки весьма полезно в контексте пользовательского интерфейса, оно позволяет вам преобразовывать таблицы в любом столбце веб-приложения, например, без изменения типов.