2016-03-29 12 views
1

Я создал функцию, которая будет анализировать строку длиной 81 символ. Во время разбора его мне нужно использовать функцию с именем neighbors(Int: row, Int: col), которая возвращает все координаты, которые являются вертикальными, горизонтальными и диагональными из указанной строки и столбца. С этим списком координат мне нужно удалить значение, которое я разместил, из каждого из возможных значений, перечисленных в каждой координате. Плата представлена ​​в виде карты, и мне нужно сделать это функционально, т. Е. Без использования var.Scala итерации по карте, представленной доской

Вот мой синтаксического анализа функции:

str.zipWithIndex.map{ 
    case (digit, index) => ((index/9, index % 9), List(digit.asDigit)) 
    }.toMap 

Вот что я знаю о neighbors функции:

def neighbors(row: Int, col: Int): List[(Int, Int)] 

Например, если анализатор был на координатной (0,2), а число вошли в карта была 4, мне пришлось бы удалить 4 со всех координат по вертикали, по горизонтали и по диагонали с этой точки. Значение каждой точки представлено в виде списка возможных значений.

Мне также не предоставлена ​​функция neighbor.

Спасибо за помощь!

+0

первый - я думал, что [предложение Карла] (http://stackoverflow.com/questions/36266982/scala-returning-coordinate-as-tuple) был гораздо лучше дизайн для синтаксического анализа. 2nd. Трудно предложить, как использовать функцию «сосед», не видя ее точной подписи или, по крайней мере, ее возвращаемого типа данных. 3rd. Вы не можете удалить что-либо из координат, которые еще не были заполнены, поэтому из вашего описания, кажется, что «сосед» должен быть вызван для каждого элемента после завершения 'parse'. – jwvh

+0

Согласен, предложение Карла было замечательным. Я понял, как заполнять пустые ячейки списком. Когда я разместил этот вопрос, я еще не понял этого. Я уточню вопрос. Кроме того, я добавлю подпись функции «сосед». Благодаря! – Colby

ответ

1

Если я правильно понял ваш вопрос, это о том, как мутировать вещи (в этом случае удалить из Map), оставаясь функциональным?

Если да, есть два подхода:

  1. Создать хвост рекурсивную функцию, которая вызывается для каждой итерации со списком оставшихся элементов для обработки и текущее состояние вашего «изменчивый» данные:

    @tailrec 
    def process(
        input: List[(Char, Int)], 
        board: Map[Any, Any], 
        resultAccum: List[Result]): List[Result] = input match { 
        case Nil => resultAccum.reverse 
        case (char, pos) :: tail => 
        // do the processing 
        val updatedBoard = board - ??? // create update version of the board 
        val updateResults = ??? :: resultAccum 
        process(tail, updatedBoard, updateResults) 
    } 
    
  2. Или вы можете использовать foldLeft, что делает тот же, но выглядит короче:

    input.foldLeft((initialBoard, List[Result]())) { 
        case ((board, resultsAccum), (char, pos)) => 
        val updatedBoard = board - ??? // create update version of the board 
        val updateResults = ??? :: resultsAccum 
        (updatedBoard, updateResults) 
    }._2.reverse 
    

    Начальное состояние foldLeft содержит начальное состояние платы и пустой список результатов.