2013-12-19 3 views
3

Должно быть, я делаю что-то неправильно. Я прихожу из фона Java, поэтому этот материал должен быть легким.Scala Списки и опция

Я хотел создать отображение между ключом и несколько значений, проведенных в списке:

var keys = Map[String, ListBuffer[String]]() 

Однако, я не могу показаться, чтобы добавить значение в списке !!! Что я делаю не так??

def put(key: String, value: String) = { 
    var valueOption = keys.get(key) 
    var values = valueOption.getOrElse(ListBuffer) 
    values += value 
    // value not added 
} 

Я не хочу использовать Multimap, потому что мне нужно сделать некоторые другие операции, которые не легко сделать с Multimap.

Пожалуйста, помогите.

Благодаря

+1

Вы используете изменяемую или неизменяемую карту? –

+0

импорт scala.collection.mutable.HashSet импорт scala.collection.mutable.ListBuffer import scala.collection.mutable.Map –

ответ

7

Другие ответы правильные о том, как вы не ставите новый ListBuffer обратно в Map, но их примерный код является подробным. У изменчивого Map есть getOrElse и getOrElseUpdate методы для этого. Кроме того, используйте val не var для местных жителей и члена keys, если у вас нет причин не делать этого. Я иногда предпочитаю append до +=.

def put(key: String, value: String) = { 
    keys.getOrElseUpdate(key, ListBuffer()) += value 
} 
4

Проблема в том, здесь:

var valueOption = keys.get(key) 
var values = valueOption.getOrElse(ListBuffer) 

Для любого несуществующего ключа, keys.get будет возвращать NoneOption. Затем вы вызываете getOrElse, а так как используется «else» (потому что это None), инициализируется новый ListBuffer. Однако это все, что происходит.

В частности, новый ListBufferНЕ автоматически помещается на карту. Такая операция не имеет смысла - getOrElse является частью API Option, он не может «знать» о какой-либо коллекции, из которой генерируется Option.

Для того, чтобы исправить возникшую проблему, необходимо ввести . В качестве примера, если вы используете изменяемые Карта:

def put(key: String, value: String) = { 
     var valueOption = keys.get(key) 
     var values = valueOption.getOrElse {val b = ListBuffer.empty[String]; keys.put(key,b); b;} 
     values += value 
} 
0

проблема в том, что с помощью вызова getOrElse(ListBuffer) вы не вставить новый ListBuffer в карте. Так что вам нужно добавить дополнительный шаг:

def put(key: String, value: String) = { 
    var valueOption = 
    var values = keys.get(key) match { 
    case None => // key not yet defined 
     buffer = ListBuffer() 
     // insert into map! 
     keys += key -> buffer 
     buffer 
    case Some(buffer) => buffer // key is already defined just return it 
    } 
    values += value 
} 

Обратите внимание, что для keys += key -> buffer работать, я предполагаю, что вы используете изменяемую Map (импорт из scala.collection.mutable.Map) неизменной вместо внесения карты по умолчанию

+0

Похож на лучший ответ, но не смог его скомпилировать (вторая строка 'var valueOption =' просто не работает. Тогда я не могу понять что происходит. Я не понимаю строку 'case Some (buffer) => buffer' - этот метод ничего не возвращает. И' buffer' кажется необъявленным. Mystery. –

0

getOrElse будет возвращать по умолчанию ListBuffer, который является пустым ListBuffer, если ключ не существует. Вам нужно будет связать это с вами ключом.

Смежные вопросы