Hi, there is a problem with my code but I can't fi...
# getting-started
n
Hi, there is a problem with my code but I can't figure out what it is. Basically, when I select distinct characters, the fourth one onwards gets double its value. But say I select four Es (or four of any same character), the fourth E is not multiplied by 2.
Copy code
fun getWordValue() {
        val workingArray = repository.arr.distinct()
        val list = mutableListOf(0)

        word.value!!.forEach { c ->
            workingArray.forEach {
                if (it.name.contains(c)) {
                    when (c) {
                        word.value!![0] -> list.add(it.value)
                        word.value!![1] -> list.add(it.value)
                        word.value!![2] -> list.add(it.value)
                        else -> list.add((it.value * 2))
                    }
                }
            }
        }
        wordValue.value = list.sum()
        saveWordValue(wordValue.value!!)
    }
I'd be grateful for some help, thanks!
s
This is a bit hard to understand because the code mentions a few things that are defined elsewhere. Can you simplify the example at all? Either that, or give some more info about what
repository
,
word
and
wordValue
are.
1
j
What do you mean by select? It'd be nice to extract just the problematic piece of code for reproducibility. Here this function is entangled with many other global things that you read or write to (which by the way is a smell, given the name of the function).
@Sam you beat me to it 😄
s
Just barely 😄
n
Thanks, let me think 🙂
I have a list of scrabble letters which form my array in my repo. The reason I put
distinct
in my
workingArray
is that some of the scrabble letters are repeated several times. Each letter has a name and a value.
Then, the game requires that I make words that I check in a database to see if they exist. For each word, the first 3 letters have their own number of points. If the word is longer each subsequent letter has double the points.
Maybe my code is too clumsy. I'll try and sort something out.
This is in my ViewModel by the way.
s
The first suggestion that comes to mind is to change
Copy code
word.value!!.forEach { c ->
to
Copy code
word.value!!.forEachIndexed { i, c ->
Where
i
will give you the position of the character in the word.
g
Given a character and its index in the word, can you find its value?
j
Given a character and its index in the word, can you find its value?
Actually this would be easy if instead of converting the letters array by just using
distinct()
you used a
Map<Char, Int>
from letter to value:
Copy code
val lettersToValues = repository.arr.associate { it.name to it.value }
n
Sorry for the late reply; I went for a walk... Thank you, I'll try out your suggestions! 😊
n
I don't know if anyone answered the question of what the problem is with the existing code. The problem is that your
when
statement will always hit the first condition in the scenario you described because it's comparing the values. So if your word is "EXCEPT", the first "E" and the fourth "E" will match
word.value!![0]
because that evaluates to "E".
🙏 1
n
Thanks for this! I managed to make it work in the end by getting rid of the
when
statement in order to make my code less awkward, and using the suggestions that were made above. But it's good to know why this did not work in the first place. 😊 Here is what the code looks like now:
Copy code
fun getWordValue() {
        val list = mutableListOf(0)
        val lettersToValues = repository.arr.associate { it.name to it.value }

        word.value!!.forEachIndexed() { i, c: Char ->
            if (i in 0..2) {
                list.add(lettersToValues.getValue(c.toString()))
            } else {
                list.add(lettersToValues.getValue(c.toString()) * 2)
            }
        }
        wordValue.value = list.sum()
        saveWordValue(wordValue.value!!)
    }
j
Also, why do you add to a list if all you want is a sum? You could just increment a total instead
g
this seems like a great use case for fold, if you want to avoid the mutable list altogether
s
I’m a little confused by your code here. You’re calling
lettersToValues.getValue(…)
but you don’t seem to do anything with the result. In an earlier version of your code you were adding it to a list, I think.
c.toString().sumOf { i }
also looks odd, and probably doesn’t do what you want it to.
n
Yes, it's just that someone said it was useless to add it to a list
s
To answer your question, though, I can’t see anything obvious that would make the code behave differently on/after the tenth loop iteration.
👍 1
n
but even adding it to a list causes the same issue
ok thanks, I need to look elsewhere in my code then 🙂
j
When I said to not add to a list, I also mentioned incrementing a counter instead. Basically instead of adding all elements to a list and then going through the list to add them all, you could use a variable that keeps the total-so-far, and increment it. But you still need to use the value anyway. You could also use
fold
which is a functional way of doing it.
😊 1
🙏 1