манипуляция списком скала: это хорошая скала? - PullRequest
1 голос
/ 28 мая 2011

Я написал некоторый код в scala для разрешения относительных (файловых) путей, см. Код ниже. Я храню пути в виде списков строк, и когда я вычисляю относительный путь, я использую переменную изменяемого списка, в которой я храню измененные копии списка, над которым я работаю.

У меня есть ощущение, что это, вероятно, не самый лучший способ сделать это, или это так? Должен ли я использовать изменяемый список и манипулировать этим? Или я должен использовать только неизменяемые списки, никаких переменных и функциональную версию? Как должен быть написан метод «относительный»?

class PathInfo(e: List[String]) {

    val elements=e;

    def relative(s : String) :PathInfo= relative(PathInfo.fromString(s));

    def relative(that : PathInfo) : PathInfo = {
        var list : List[String]=List();
        for (item <- elements) {
            list = list :+ item;
        }
        for (item <- that.elements) {
            item match {
                case "." => ;
                case ".." => list = list dropRight(1);
                case other => list = list :+ other;
            }
        }
        new PathInfo(list);
    }

    override def toString : String = {
        elements.mkString("/");
    }

}

object PathInfo {
    def fromString(s : String) : PathInfo={
        new PathInfo(List.fromString(s,'/'));
    }
}

Ответы [ 2 ]

5 голосов
/ 28 мая 2011

В общем, петли вида:

var foo = initialFoo
for (x <- xs) foo = f(foo, x)

можно заменить на складной левый:

val foo = xs.foldLeft(initialFoo)(f)

В этом конкретном случае версия foldLeft будет выглядеть так:

val list = that.elements.foldLeft(this.elements) { (xs, x) => 
  x match {
    case "." => xs
    case ".." => xs init
    case other => xs :+ other
  }
}

Кстати, нет необходимости перебирать список элементов, чтобы скопировать его для начального значения list - это неизменный список, поэтому его можно безопасно использовать.

3 голосов
/ 28 мая 2011

Я просто собираюсь внести небольшое изменение в предложение Дэвида; Я обнаружил, что предпочитаю деконструировать элементы кортежа в foldLeft напрямую:

val list = that.elements.foldLeft(this.elements) { 
  case (xs, ".")  => xs
  case (xs, "..") => xs init
  case (xs, x)    => xs :+ x
}

Теперь здесь загадка. Это работает, и делает это чудесным образом ... но вы можете выяснить, почему PartialFunction [(List [String], String), List [String]] повышен до Function2 [List [String], String , Список [String]]? :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...