#list #scala #collections #map #set
#Список #scala #Коллекции #словарь #установить
Вопрос:
имея список упорядоченных строк для сравнения с другим списком, я решил реализовать его в виде карты, в которой ключом является первый символ строки, а значением — список строк с тем же первым символом. Короче говоря, у меня есть что-то вроде этого:
var list1:Map[Char, List[String]] = Map('a' -> List("alone", "away"))
var list2:List[String] = List("I", "am", "alone", "at", "home", "watching", "batman", "XD")
Теперь, после реализации моего кода таким образом, с ними «сложно» работать, пытаясь рассматривать первый как простой список, поэтому мне было интересно, есть ли другой, более элегантный способ решения этой проблемы.
Если мне нужно проверить, есть ли в list1 значение «alone», я должен сначала получить ключ ‘a’, а затем вызвать метод contains. Мне пришлось реализовать нечто подобное.
if ( list1( "alone".charAt(0) ).contains( "alone" ) ) ...
Некрасиво каждый раз извлекать ключ, а затем сравнивать списки, и я хотел бы создать новую карту (или список), которая реализует это под капотом (она автоматически извлекает ключ, а затем работает со списком).).
Что вы предлагаете?
Спасибо.
РЕДАКТИРОВАТЬ: я переписал часть вопроса, уточнив некоторые моменты. Первый список упорядочен, второй — нет.
Комментарии:
1. у вас есть список упорядоченных строк? Или упорядоченный список строк? И почему у вас есть эта проводная карта? Почему бы не использовать простой список?
2. Ну, у меня есть список упорядоченных строк, и я реализовал свой код таким образом, полагая, что это может быть быстрее для выполнения поиска и замены и некоторых других вещей. Я имею в виду, что быстрее выполнять поиск в меньшем списке, чем во всем списке, нет?
3. Вероятно, вам лучше всего использовать
Vector
. Это довольно эффективно при подобных операциях.4. В чем преимущества Vector? В документации scala-lang нет описания.
5. Я не знаком со scala, но не могли бы вы просто использовать наборы и их операции? — В любом случае.. В этом случае с отсортированными списками, почему бы не выполнить итерацию по одному списку, сравнивая каждый элемент с элементом в той же позиции в другом списке? O (n)
Ответ №1:
Из всего, что я видел, вам действительно нужен просто список. Поэтому используйте список. (Или, возможно, SortedSet http://www.scala-lang.org/api/current/scala/collection/SortedSet.html )
Похоже, вас беспокоит производительность, но вы не указываете, какая часть какого алгоритма должна замедляться, и насколько быстрее она должна выполняться, и не приводите убедительных аргументов в пользу того, что выбранный вами подход соответствует этим требованиям к производительности. Итак, еще раз: просто используйте список. Затем измерьте производительность. Если это действительно замедляется, создайте на его основе тестовый код post и результаты здесь и укажите, как быстро это должно выполняться.
Тогда люди смогут помочь.
Комментарии:
1. Согласен, я не заметил, что там также был HashSet … Знаете, когда вы пришли с языка сценариев (autoit), вы не можете ожидать, что будете знать все. Спасибо за предложение. Пока.
Ответ №2:
Я не уверен, почему использование maps поможет вам сравнить списки строк, но в любом случае:
Если вы не возражаете против использования изменяемой коллекции и уверены, что в вашем списке нет повторов (так что вы действительно можете использовать set), то вы можете использовать MultiMap
признак:
import scala.collection.mutable._
val mm = new HashMap[Char,Set[String]] with MultiMap[Char,String]
Seq("alone","away").foreach(s => mm.addBinding(s(0),s))
scala> mm
res2: scala.collection.mutable.HashMap[Char,scala.collection.mutable.Set[String]]
with scala.collection.mutable.MultiMap[Char,String] =
Map(a -> Set(alone, away))
scala> mm.entryExists('a',"alone")
К сожалению, многозадачность исчезает, когда вы используете операцию сбора данных (тогда это просто простая карта от Char
до Set[String]
).
Комментарии:
1. Я хотел решить (‘a’, «alone») часть… Я хочу сделать что-то как mm.contains («alone»), и это автоматически сделает что-то как mm ( «alone».charAt(0)).contains( «alone»)…
2. @DDB — Если вам на самом деле никогда не нужен
'a'
сам по себе, я думаю, это явный признак того, что вы не применяете правильный подход к решению вашей проблемы. Кроме того, не забывайте, что вы можете простоdef has(m: Map[Char,List[String]], s: String) = if (s.length>0) m.get(s.charAt(0)).map(_ contains s).getOrElse(false) else false
использовать это вместо того, чтобы каждый раз вводить весь беспорядок.3. Возможно, я мог бы решить проблему, используя неявное определение… Я не думал об этом таким образом…
4. @DDB — Вы могли бы использовать неявные преобразования, если хотите, чтобы синтаксис m имел «яблоки» вместо has(m, «apples»). В противном случае последнее более эффективно.