The logic of your code is not very functional to begin with.
In functional programming, you usually deal with immutable data, on which you apply functions to get new immutable values. Here, you're trying to modify the value of answer_array imperatively.
The idiomatic way to do it would be the following:
val answerArray = my2DArray.zipWithIndex.flatMap {
case (row, i) => row.zipWithIndex.filter{
case (col, j) => col == someValue
}.map {
case (col, j) => (someValue, (i, j))
}
}
This is not very readable code, especially for a beginner, so let's decompose it:
first we traverse our 2D array (with indices) using flatMap, which takes a function to act on each element. This function must return another array for each element, and will flatten all these arrays into a single one (hence the "flat" in flatMap).
the elements of the array are pairs of an element of the initial array, ie a row, and its index, so we pattern match on this pair, to be able to define our function properly.
now, for each row, what do we want to do? keep only the elements which satisfy the condition, so we filter on it, with the predicate (which is just a fancy name for function returning a Boolean), returning the array containing only the values satisfying the condition.
however, we do not want these values, but a transformation of them, so we apply map to our array. map is the same as flatMap, only its argument does not need to return arrays, since the return value will not be flattened (it just makes an array of the images of the element of the first array by the given function).
what function do we want to apply on the remaining elements? Well, we just want the triple (someValue, (i, j))
notice that I used camelCase, which is also the idiomatic way to name your variables in scala (although this is in no way necessary)
Ok, so we have some nice code that do what we want, but it is not very readable. Thankfully, the language as a nice syntax sugar called for-comprehension to replace flatMaps, maps and filters into a more imperative style. Note that this is just for easiness of code-writing, and that, at compile-time, the code will be replaced by what I described above (or something close to it).
val answerArray = for {
(row, i) <- 2DArray.zipWithIndex
(col, j) <- row.zipWithIndex
if col == someValue
} yield (someValue, (i, j))
Each <- line traverses the rhs array, assigning the lhs name to its elements (with some pattern matching as a bonus)
Each if row represent a condition on the values we want to keep
the yield part is the value we want to get in each element of our final array, depending on the values we extracted in each array.