2013-09-08 2 views
2

Я изучаю Scala, и я хотел бы преобразовать некоторые из моих старых алгоритмов в Scala.Scala Code - неизменяемые проблемы с набором

У меня очень простой Java-код, который печатает superSet (комбинация всех возможных наборов, включая пустой набор и сам набор).

public static Set<Set<Integer>> createSuperSet(Set<Integer> originalSet){ 
    Set<Set<Integer>> superSet = new HashSet<Set<Integer>>(); 

    if (originalSet.size() == 0){ 
     Set<Integer> empty = new HashSet<Integer>(); 
     superSet.add(empty); 
     return superSet; 
    } 

    List<Integer> list = new ArrayList<Integer>(originalSet); 
    Integer head = list.get(0); 
    Set<Integer> rest = new HashSet<Integer>(list.subList(1, list.size())); 
    for (Set<Integer> set : createSuperSet(rest)){ 
     Set<Integer> newSet = new HashSet<Integer>(); 
     newSet.add(head); 
     newSet.addAll(set); 
     superSet.add(newSet); 
     superSet.add(set); 
    }  
    return superSet; 
} 

Сейчас я пытаюсь добиться ту же функциональность в Scala:

def createSuperSet(originalSet: Set[Int]): Set[Set[Int]] ={ 
    val superSet = Set[Set[Int]]() 

    originalSet.toList match { 

     case List() => {superSet + Set[Int]()} 

     case head::restAsList => { 
     val rest = restAsList.toSet[Int] 
     val result = createSuperSet(rest) 
     result.foreach(f=>{ 
      val newSet:Set[Int] = f + head 
      superSet + f +newSet 
     }) 
     superSet 
     } 
    } 
    } 

, но, к сожалению, этот код возвращает пустой набор. Я подозреваю, что эта проблема возникает из-за неиспользованного использования коллекции. Я пытался запустить его в Debugger, и я вижу, что рекурсивный вызов функции всегда возвращает пустой набор, и мой код никогда не попадает в функцию foreach.

Пожалуйста, помогите. Любые мысли приветствуются.

ответ

4

В idiomatic scala оператор +-, ++ и т. Д.) Применительно к неизменяемым коллекциям создает новую коллекцию - в противном случае они не были бы неизменными. Вместо этого вам необходимо объединить модификацию с another piece of syntactic sugar, под которым при добавлении = оператору присваивается результат оператора левой переменной: superSet += f + newSet.

+0

superSet + = f + newSet выражение не может быть скомпилировано. –

+0

Вы объявили его как 'val', поэтому' superSet' не может быть переназначен. –

0

Я решил проблему так:

def createSuperSet(originalSet: Set[Int]): Set[Set[Int]] ={ 
    var superSet = Set[Set[Int]]() 

    originalSet.toList match { 

     case List() => {superSet + Set[Int]()} 

     case head::restAsList => { 
     val rest = restAsList.toSet[Int] 
     val result = createSuperSet(rest) 
     result.map(f=>{ 
      superSet = superSet + f+ (f+head) 
     }) 
     superSet 
     } 
    } 
    } 

работает println(createSuperSet(Set[Int](1,2,3))

отпечатки

Set(Set(), Set(3, 1), Set(2), Set(2, 1), Set(3, 2), Set(3), Set(3, 2, 1), Set(1)) 

, но я буду очень рад узнать, есть ли более элегантное решение