2016-03-29 1 views
1

J'ai créé une fonction qui va analyser une chaîne de 81 caractères. En l'analysant, j'ai besoin d'utiliser une fonction appelée neighbors(Int: row, Int: col) qui retourne toutes les coordonnées verticales, horizontales et diagonales de la ligne et de la col. Avec cette liste de coordonnées, je dois enlever la valeur que j'ai placée de chacune des valeurs possibles listées à chaque coordonnée. Le tableau est représenté sous forme de carte, et je dois le faire de manière fonctionnelle, c'est-à-dire sans utiliser de var.Scala itérer sur une carte représentée par un tableau

Voilà ma fonction d'analyse syntaxique:

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

Voici ce que je sais sur la fonction neighbors:

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

Par exemple, si l'analyseur était sur la coordonnée (0,2), et le nombre est entré dans la carte était 4, je devrais supprimer 4 de toutes les coordonnées verticales, horizontales et diagonales à partir de ce point. La valeur de chaque point est représentée sous forme de liste de valeurs possibles.

Je ne reçois pas non plus la mise en œuvre de la fonction neighbor.

Merci pour l'aide!

+0

1er - Je pensais que [la suggestion de Karl] (http://stackoverflow.com/questions/36266982/scala-returning-coordinate-as-tuple) était une bien meilleure conception pour votre analyseur. 2ème - Il est difficile de suggérer comment utiliser la fonction 'neighbor' sans voir sa signature exacte, ou au moins son type de données de retour. 3ème - Vous ne pouvez rien enlever des coordonnées qui n'ont pas encore été remplies, donc il semblerait, d'après votre description, que 'neighbor' devrait être appelé sur chaque élément après que' parse' soit fini. – jwvh

+0

Je suis d'accord, la suggestion de Karl était super. J'ai compris comment avoir des cellules vides avec une liste. Quand j'ai posté cette question, je ne l'avais pas encore compris. Je vais mettre à jour la question. Aussi, je vais ajouter la signature de la fonction 'neighbor'. Merci! – Colby

Répondre

1

Si j'ai bien compris votre question, c'est sur la façon de muter des choses (dans ce cas, retirer du Map) tout en restant fonctionnel?

Si oui, il y a deux approches:

  1. Créez fonction récursive de la queue qui est appelée à chaque itération la liste des éléments restants à traiter et de l'état actuel de vos données « mutable »:

    @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. Ou vous pouvez utiliser foldLeft, qui fait la même, mais il semble plus court:

    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 
    

    L'état initial du foldLeft contient l'état initial de la carte et la liste vide des résultats.