0

I have two arrays:

GlobalArray:Array(Int,Array[String]) and SpecificArray:Array(Int,Int).

The first Int in both of them is a key and I would like to get the element corresponding to that key from the GlobalArray.

In pseudocode:

val v1
For each element of SpecificArray
    Get the corresponding element from GlobalArray to use its Array[String]
         If (sum <= 100)
             for each String of the Array
                 update v1 
                 // ... some calculation
                 sum += 1

println (v1)

I know using .map() I could go through each position of the SpecificArray, but so far I was able to do this:

SpecificArray.map{x => val in_global = GlobalArray.filter(e => (e._1 == x._1))
                       // I don't know how to follow
                  }
diens
  • 639
  • 8
  • 26

3 Answers3

1

How sum affects the logic and what exactly is v1 is not clear from your code, but it looks like you do search through GlobalArray many times. If this is so, it makes sense to convert this array into a more search-friendly data structure: Map. You can do it like this

val globalMap = GlobalArray.toMap

and then you may use to join the strings like this

println(SpecificArray.flatMap({case (k,v) => globalMap(k).map(s => (k,v,s))}).toList)

If all you need is strings you may use just

println(SpecificArray.flatMap({case (k,v) => globalMap(k)}).toList)

Note that this code assumes that for every key in the SpecificArray there will be a matching key in the GlobalArray. If this is not the case, you should use some other method to access the Map like getOrElse:

println(SpecificArray.flatMap({case (k,v) => globalMap.getOrElse(k, Array()).map(s => (k,v,s))}).toList)

Update

If sum is actually count and it works for whole "joined" data rather than for each key in the SpecificArray, you may use take instead of it. Code would go like this:

val joined = SpecificArray2.flatMap({case (k,v) => globalMap.getOrElse(k, Array()).map(s => (s,v))})
        .take(100) // use take instead of sum

And then you may use joined whatever way you want. And updated demo that builds v1 as joined string of form v1 += String_of_GlobalArray + " = " + 2nd_Int_of_SpecificArray is here. The idea is to use mkString instead of explicit variable update.

SergGr
  • 23,570
  • 2
  • 30
  • 51
  • Sorry if I wasn't clear enough. I put `sum` because if it get 100 I don't need to continue. And `v1` is a variable which I want to update, for instance: `v1 = String_of_GlobalArray + " = " + 2nd_Int_of_SpecificArray` (or passing these values to a function). So, I need a value from each one. – diens May 21 '18 at 01:30
  • 1
    @diens, I updated my answer to be closer to what it seems you want. Also take a look at the updated demo, – SergGr May 21 '18 at 10:28
1

Note needs more optimization

Convert GlobalArray to Map for faster lookup.

val GlobalMap = GlobalArray.toMap

SpecificArray.flatMap(x => GlobalMap(x._1))
.foldLeft(0)((sum:Int, s:String) => {
    if(sum<=100) {
    // update v1
    // some calculation
    }
    sum+1
})

If not all keys of SpecificArray is present in GlobalMap then use GlobalMap.getOrElse(x._1, Array())

shanmuga
  • 4,329
  • 2
  • 21
  • 35
  • Wow, thank you for your answer. Sorry, but I'm still stuck when I have to update `v1` because I need to use the second `Int` value from `SpecificArray` mixed with the `s` parameter. – diens May 21 '18 at 02:18
  • Mutation (updates to variable) is discouraged in scala. Can you give more details about the purpose of `v1` – shanmuga May 21 '18 at 10:19
  • `v1` is a result to apply a function using the second `Int` value from `SpecificArray` and each `String` of the Array (the second field of `GlobalArray`) – diens May 21 '18 at 14:57
1

How about something like below, I would prefer to for comprehension code which has better readability.

var sum:Int = 0
var result:String = ""
for {
  (k1,v1) <- SpecificArray //v1 is the second int from specific array
  (k2,values) <- GlobalArray if k1 == k2  //values is the second array from global array
  value  <- values if sum < 100  //value is one value frome the values
   _ = {sum+=1; result += s"(${v1}=${value})"} //Update something here with the v1 and value
 } yield ()

println(result)
Binzi Cao
  • 1,075
  • 5
  • 14
  • Could I use this on SpecificArray and GlobalArray with different number of elements? – diens May 21 '18 at 14:52
  • This way is the most readable for me, but how about performance? Is there any difference between using for or flatMap? Now I'm doing local tests but I have to use a cluster to run this. – diens May 22 '18 at 13:35
  • 1
    The for comprehension is a syntax short cut for flatmap and map. Here is a good discussion about it https://stackoverflow.com/questions/14598990/confused-with-the-for-comprehension-to-flatmap-map-transformation – Binzi Cao May 22 '18 at 23:38