Below sample data
val combineList = List(("A",12),("B",11),("C",12),("D",14),("E",23),("F",12),("D",53),("C",23),("B",12),("A",22),("E",21),("F",12),("C",21),("B",34),("A",34),("G",67),("D",23),("E",21),("F",12),("D",31),("B",41),("E",14),("F",15),("G",18),("A",11),("C",10),("D",9),("A",13),("E",1),("F",14))
and
val X = 98
Now want final output as below,
first group by all values as below
val groupKey = List(Map("A"->List(12,22,34,11,13)),Map("B"->List(11,12,34,41)),Map("C"->List(12,23,21,10)),Map("D"->List(14,53,23,31,9)),
Map("E"->List(23,21,21,14,1)),Map("F"->List(12,12,12,15,14)),Map("G"->List(67,18)))
Second substract X from groupKey List values here X always gretter than List values so second output will be as
val substrackValues = List(Map("A"->List(86,76,34,87,85)),Map("B"->List(87,86,34,57)),Map("C"->List(86,75,77,88)),Map("D"->List(84,45,75,31,89)),
Map("E"->List(75,77,77,84,97)),Map("F"->List(86,86,86,15,84)),Map("G"->List(31,80)))
Consider
combineList.groupBy(_._1).mapValues(xs => xs.map(v => X-v._2))
which delivers
Map(E -> List(75, 77, 77, 84, 97), F -> List(86, 86, 86, 83, 84), A -> List(86, 76, 64, 87, 85), G -> List(31, 80), B -> List(87, 86, 64, 57), C -> List(86, 75, 77, 88), D -> List(84, 45, 75, 67, 89))
Note the embedded maps in groupKey above are singleton maps which can well be represented with tuples of [(String,List[Int])] or even better agglomerated into one map.
In the solution proposed here after grouping by first tuple element, we transform each element in each list by the value of X.
Related
output : prime numbers
2
3
()
5
()
7
()
()
i want as
2
3
5
7
def primeNumber(range: Int): Unit ={
val primeNumbers: immutable.IndexedSeq[AnyVal] =
for (number :Int <- 2 to range) yield{
var isPrime = true
for(checker : Int <- 2 to Math.sqrt(number).toInt if number%checker==0 if isPrime) isPrime = false
if(isPrime) number
}
println("prime numbers")
for(prime <- primeNumbers)
println(prime)
}
so the underlying problem here is that your yield block effectively will return an Int or a Unit depending on isPrime this leads your collection to be of type AnyVal because that's pretty much the least upper bound that can represent both types. Unit is a type only inhabited by one value which is represented as an empty set of round brackets in scala () so that's what you see in your list.
As Puneeth Reddy V said you can use collect to filter out all the non-Int values but I think that is a suboptimal approach (partial functions are often considered a code-smell depending on what type of scala-style you do). More idiomatic would be to rethink your loop (such for loops are scarcely used in scala) and this could be definitely be done using a foldLeft operation maybe even something else.
You can use collect on your output
primeNumbers.collect{
case i : Int => i
}
res2: IndexedSeq[Int] = Vector(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97)
The reason is if else returning two types of value one is prime value and another is empty. You could return 0 in else case and filter it before printing it.
scala> def primeNumber(range: Int): Unit ={
|
| val primeNumbers: IndexedSeq[Int] =
|
| for (number :Int <- 2 to range) yield{
|
| var isPrime = true
|
| for(checker : Int <- 2 to Math.sqrt(number).toInt if number%checker==0 if isPrime) isPrime = false
|
| if(isPrime) number
| else
| 0
| }
|
| println("prime numbers" + primeNumbers)
| for(prime <- primeNumbers.filter(_ > 0))
| println(prime)
| }
primeNumber: (range: Int)Unit
scala> primeNumber(10)
prime numbersVector(2, 3, 0, 5, 0, 7, 0, 0, 0)
2
3
5
7
But we should not write the code the way you have written it. You are using mutable variables. Try to write code in an immutable way.
For example
scala> def isPrime(number: Int) =
| number > 1 && !(2 to number - 1).exists(e => e % number == 0)
isPrime: (number: Int)Boolean
scala> def generatePrimes(starting: Int): Stream[Int] = {
| if(isPrime(starting))
| starting #:: generatePrimes(starting + 1)
| else
| generatePrimes(starting + 1)
| }
generatePrimes: (starting: Int)Stream[Int]
scala> generatePrimes(2).take(100).toList
res12: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101)
Right now I have 2 lists in Scala:
val one = List(50, 10, 17, 8, 16)
val two = List(582, 180, 174, 159, 158)
These lists are going to be of the same length, and right now I'm looking to divide each element of the first list by a corresponding element in the second. In other words, I want a list that consists of:
List(50/582, 10/180, etc...)
Is there a set operation that accomplishes this that can be done without looping?
Thank you!
You can use the zip function.
val one = List(50, 10, 17, 8, 16)
val two = List(582, 180, 174, 159, 158)
one.zip(two).map {
case (a, b) => a.toDouble/b.toDouble
}
I would like to convert every single word into decimal ascii.
for example "RESEP" :
R = 82,
E = 69,
S = 83,
E = 69,
P = 80
my code is:
val LIST_KEYWORD = List("RESEP",
"DAGING SAPI",
"DAGING KAMBING")
val RUBAH_BYTE = LIST_KEYWORD.map(_.split(",")).map
{
baris =>
(
baris(0).getBytes
)
}
and then, I get stuck and I don't know what I am supposed to do next.
scala> "RESEP".map(_.toByte)
res1: scala.collection.immutable.IndexedSeq[Byte] = Vector(82, 69, 83, 69, 80)
scala> "RESEP".map(x => x -> x.toByte)
res2: scala.collection.immutable.IndexedSeq[(Char, Byte)] = Vector((R,82), (E,69), (S,83), (E,69), (P,80))
scala> val LIST_KEYWORD = List("RESEP",
| "DAGING SAPI",
| "DAGING KAMBING")
LIST_KEYWORD: List[String] = List(RESEP, DAGING SAPI, DAGING KAMBING)
scala> LIST_KEYWORD.map(_.map(_.toByte))
res3: List[scala.collection.immutable.IndexedSeq[Byte]] = List(Vector(82, 69, 83, 69, 80), Vector(68, 65, 71, 73, 78, 71, 32, 83, 65, 80, 73), Vector(68, 65, 71, 73, 78, 71, 32, 75, 65, 77, 66, 73, 78, 71))
scala> LIST_KEYWORD.map(_.map(x => x -> x.toByte))
res4: List[scala.collection.immutable.IndexedSeq[(Char, Byte)]] = List(Vector((R,82), (E,69), (S,83), (E,69), (P,80)), Vector((D,68), (A,65), (G,71), (I,73), (N,78), (G,71), ( ,32), (S,83), (A,65), (P,80), (I,73)), Vector((D,68), (A,65), (G,71), (I,73), (N,78), (G,71), ( ,32), (K,75), (A,65), (M,77), (B,66), (I,73), (N,78), (G,71)))
I wasn't sure if groupBy, takeWhile, or grouped would achieve what I wanted to do. I need to develop a function that automatically groups a list of numbers according to the interval I want to specify. The use case is taking a list of ages and sorting them into dynamic age categories (like 1-5, 5-10, etc.). It would need to be dynamic since the user may want to change the intervals.
For example, I have the list of numbers: List(103, 206, 101, 111, 211, 234, 242, 99)
I can interval by 10, or by 100. Then the result of an input of 100 would be: List(List(99),List(101,103,111),List(206,211,234,242)).
I searched Google and SO for the last hour but couldn't find anything. Thanks for the help!
You will want groupBy:
val xs = List(103, 206, 101, 111, 211, 234, 242, 99)
xs.groupBy(_ / 100)
// Map(0 -> List(99), 1 -> List(103, 101, 111), ...)
grouped just creates subsequent clumps of a given size, not looking at the actual elements. takeWhile just takes the leading elements as long as a predicate holds.
You can use the withDefaultValue method on the resulting map to make it appear as an indexed sequence, where some entries are empty:
val ys = xs.groupBy(_ / 100) withDefaultValue Nil
ys(0) // List(99)
ys(4) // List() !
Here's an approach that generates the ranges and filters for values within them. I think the l.groupBy(_ / 100).values is preferable though.
val interval = 100
//This gives List(Vector(0, 100), Vector(100, 200), Vector(200, 300))
val intervals = 0 until l.max + interval by interval sliding(2)
for(interval <- intervals;
within <- List(l.filter(x => x > interval(0) && x <= interval(1)))
) yield within
With val l = List(103, 206, 101, 111, 211, 234, 242, 99) this gives:
List[List[Int]] = List(List(99), List(103, 101, 111), List(206, 211, 234, 242))
I have a 3-tuple list like the following [I added line breaks for readability]:
(2, 127, 3)
(12156, 127, 3)
(4409, 127, 2) <-- 4409 occurs 2x
(1312, 127, 12) <-- 1312 occurs 3x
(4409, 128, 1) <--
(12864, 128, 1)
(1312, 128, 1) <--
(2664, 128, 2)
(12865, 129, 1)
(183, 129, 1)
(12866, 129, 2)
(1312, 129, 10) <--
I want to sum up based on the first entry. The first entry should be unique.
The result should look like this:
(2, 127, 3)
(12156, 127, 3)
(4409, 127, 3) <- new sum = 3
(1312, 127, 23) <- new sum = 23
(12864, 128, 1)
(2664, 128, 2)
(12865, 129, 1)
(183, 129, 1)
(12866, 129, 2)
How can I achieve this in Scala?
Try this:
list groupBy {_._1} mapValues {v => (v.head._1, v.head._2, v map {_._3} sum)}
The middle entry is preserved and it always takes the first one that appeared in the input list.
If you can just ignore the middle entry, then:
val l = List(('a,'e,1), ('b,'f,2), ('a,'g,3), ('b,'h,4))
l.groupBy(_._1).mapValues(_.map(_._3).sum)
// Map('b -> 6, 'a -> 4)
If you have to keep the middle entry around:
l.groupBy(_._1).map {
case (_, values) =>
val (a,b,_) = values.head
(a, b, values.map(_._3).sum)
}
// List(('b,'f,6), ('a,'e,4))
You could use the concept of a monoid. If the first two values of your entries build the key values and the remaining the associate value itself, you could use a Map.
Once you have a Map you may proceed like this:
Best way to merge two maps and sum the values of same key?