Interleaving iterators - scala

I wrote the following code, expecting the last print method to show the elements of both iterators combined. Instead it only shows the elements of perfectSquares. Can someone explain this to me?
object Fuge {
def main(args: Array[String]) : Unit = {
perfectSquares.takeWhile(_ < 100).foreach(square => print(square + " "))
println()
triangles.takeWhile(_ < 100).foreach(triangle => print(triangle + " "))
println()
(perfectSquares++triangles).takeWhile(_ < 100).foreach(combine => print(combine + " "))
}
def perfectSquares : Iterator[Int] = {
Iterator.from(1).map(x => x * x)
}
def triangles : Iterator[Int] = {
Iterator.from(1).map(n => (n * (n + 1)/2))
}
}
OUTPUT:
1 4 9 16 25 36 49 64 81
1 3 6 10 15 21 28 36 45 55 66 78 91
1 4 9 16 25 36 49 64 81

From the documentation on takeWhile:
/** Takes longest prefix of values produced by this iterator that satisfy a predicate.
*
* #param p The predicate used to test elements.
* #return An iterator returning the values produced by this iterator, until
* this iterator produces a value that does not satisfy
* the predicate `p`.
* #note Reuse: $consumesAndProducesIterator
*/
What this means is that the iterator stops at that juncture. What you've created is an iterator that goes far past 100 and then, at some point, starts off at 1 again. But takeWhile won't go that far because it's already run into a number higher than 100. See:
object Fuge {
def main(args: Array[String]) : Unit = {
perfectSquares.takeWhile(_ < 100).foreach(square => print(square + " "))
println()
triangles.takeWhile(_ < 100).foreach(triangle => print(triangle + " "))
println()
def interleave (a: Iterator[Int], b: Iterator[Int]): Stream[Int] = {
if (a.isEmpty || b.isEmpty) { Stream.empty }
else {
a.next() #:: b.next() #:: interleave(a, b)
}
}
lazy val interleaved = interleave(perfectSquares, triangles)
interleaved.takeWhile(_ < 100).foreach(combine => print(combine + " "))
}
def perfectSquares : Iterator[Int] = {
Iterator.from(1).map(x => x * x)
}
def triangles : Iterator[Int] = {
Iterator.from(1).map(n => (n * (n + 1)/2))
}
}
Here I'm using a stream to lazily evaluate the sequence of integers. In this way we can ensure interleaving. Note that this is just interleaved, not sorted.
This yields:
1 4 9 16 25 36 49 64 81
1 3 6 10 15 21 28 36 45 55 66 78 91
1 1 4 3 9 6 16 10 25 15 36 21 49 28 64 36 81 45
To sort during a stream, you need a BufferedIterator and to change up the interleave function a bit. This is because calling next() advances the iterator - you can't go back. And you also can't know how many items you need from list a before you need an item from list b, and vice versa. But BufferedIterator allows you to call head, which is a 'peek' and does not advance the iterator. Now the code becomes:
object Fuge {
def main(args: Array[String]) : Unit = {
perfectSquares.takeWhile(_ < 100).foreach(square => print(square + " "))
println()
triangles.takeWhile(_ < 100).foreach(triangle => print(triangle + " "))
println()
def interleave (a: BufferedIterator[Int], b: BufferedIterator[Int]): Stream[Int] = {
if (a.isEmpty || b.isEmpty) { Stream.empty }
else if (a.head <= b.head){
a.next() #:: interleave(a, b)
} else {
b.next() #:: interleave(a, b)
}
}
lazy val interleaved = interleave(perfectSquares.buffered, triangles.buffered)
interleaved.takeWhile(_ < 100).foreach(combine => print(combine + " "))
}
def perfectSquares : Iterator[Int] = {
Iterator.from(1).map(x => x * x)
}
def triangles : Iterator[Int] = {
Iterator.from(1).map(n => (n * (n + 1)/2))
}
}
And the output is:
1 4 9 16 25 36 49 64 81
1 3 6 10 15 21 28 36 45 55 66 78 91
1 1 3 4 6 9 10 15 16 21 25 28 36 36 45 49 55 64 66 78 81 91

The problems with using Streams here is that they cache all the previous data. I'd rather interleave iterators as is, without involving streams.
Something like this:
class InterleavingIterator[X, X1 <: X, X2 <: X](
iterator1: Iterator[X1],
iterator2: Iterator[X2]) extends Iterator[X] {
private var i2: (Iterator[X], Iterator[X]) = (iterator1, iterator2)
def hasNext: Boolean = iterator1.hasNext || iterator2.hasNext
def next: X = {
i2 = i2.swap
if (i2._1.hasNext) i2._1.next else i2._2.next
}
}

Related

Solving wrong forward reference error in scala [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
How to solve wrong forward reference error in scala. What exactly is that error means?
def daysInMonth(year: Int, month: Int): Int = {
val daysInMonth: Int = month match {
case 1 => 31
case 3 => 31
case 5 => 31
case 7 => 31
case 8 => 31
case 10 => 31
case 12 => 31
case 2 => {
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) 29 else 28
}
case _ => 30
}
daysInMonth
}
The below statement shows the forward reference error
println(daysInMonth(2011,12))
The error was caused by the fact that you were trying to return a variable with the same name of your function.
The solution is much simpler than you think:
object WrongForwardReference {
def main(args: Array[String]): Unit = {
println(daysInMonth(2011,12))
}
def daysInMonth(year: Int, month: Int): Int = month match {
case 1 => 31
case 3 => 31
case 5 => 31
case 7 => 31
case 8 => 31
case 10 => 31
case 12 => 31
case 2 => {
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) 29 else 28
}
case _ => 30
}
}
A simplified version is this one:
def daysInMonth(year: Int, month: Int): Int = month match {
case 1 | 3 | 5 | 7 | 8 | 10 | 12 => 31
case 2 => {
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) 29 else 28
}
case _ => 30
}

Scala tail recursive method has an divide and remainder error

I'm currently computing the binomial coefficient of two natural numbers by write a tail recursion in Scala. But my code has something wrong with the dividing numbers, integer division by k like I did as that will give you a non-zero remainder and hence introduce rounding errors. So could anyone help me figure it out, how to fix it ?
def binom(n: Int, k: Int): Int = {
require(0 <= k && k <= n)
def binomtail(n: Int, k: Int, ac: Int): Int = {
if (n == k || k == 0) ac
else binomtail(n - 1, k - 1, (n*ac)/k)
}
binomtail(n,k,1)
}
In general, it holds:
binom(n, k) = if (k == 0 || k == n) 1 else binom(n - 1, k - 1) * n / k
If you want to compute it in linear time, then you have to make sure that each intermediate result is an integer. Now,
binom(n - k + 1, 1)
is certainly an integer (it's just n - k + 1). Starting with this number, and incrementing both arguments by one, you can arrive at binom(n, k) with the following intermediate steps:
binom(n - k + 1, 1)
binom(n - k + 2, 2)
...
binom(n - 2, k - 2)
binom(n - 1, k - 1)
binom(n, k)
It means that you have to "accumulate" in the right order, from 1 up to k, not from k down to 1 - then it is guaranteed that all intermediate results correspond to actual binomial coefficients, and are therefore integers (not fractions). Here is what it looks like as tail-recursive function:
def binom(n: Int, k: Int): Int = {
require(0 <= k && k <= n)
#annotation.tailrec
def binomtail(nIter: Int, kIter: Int, ac: Int): Int = {
if (kIter > k) ac
else binomtail(nIter + 1, kIter + 1, (nIter * ac) / kIter)
}
if (k == 0 || k == n) 1
else binomtail(n - k + 1, 1, 1)
}
Little visual test:
val n = 12
for (i <- 0 to n) {
print(" " * ((n - i) * 2))
for (j <- 0 to i) {
printf(" %3d", binom(i, j))
}
println()
}
prints:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
Looks ok, compare it with this, if you want.
Andrey Tyukin's excellent example will fail with larger n, say binom(10000, 2), but can be easily adapted to use BigInt.
def binom(n: Int, k: Int): BigInt = {
require(0 <= k && k <= n)
#annotation.tailrec
def binomtail(nIter: Int, kIter: Int, ac: BigInt): BigInt = {
if (kIter > k) ac
else binomtail(nIter + 1, kIter + 1, (nIter * ac) / kIter)
}
if (k == 0 || k == n) 1
else binomtail(n - k + 1, 1, BigInt(1))
}

Scala for loop yield

I'm new to Scala so I'm trying to mess around with an example in Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition
// Returns a row as a sequence
def makeRowSeq(row: Int) =
for (col <- 1 to 10) yield {
val prod = (row * col).toString
val padding = " " * (4 - prod.length)
padding + prod
}
// Returns a row as a string
def makeRow(row: Int) = makeRowSeq(row).mkString
// Returns table as a string with one row per line
def multiTable() = {
val tableSeq = // a sequence of row strings
for (row <- 1 to 10)
yield makeRow(row)
tableSeq.mkString("\n")
}
When calling multiTable() the above code outputs:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
This makes sense but if I try to change the code in multiTable() to be something like:
def multiTable() = {
val tableSeq = // a sequence of row strings
for (row <- 1 to 10)
yield makeRow(row) {
2
}
tableSeq.mkString("\n")
}
The 2 is being returned and changing the output. I'm not sure where it's being used though to manipulate the output and can't seem to find a similar example searching around here or Google. Any input would be appreciated!
makeRow(row) {2}
and
makeRow(row)(2)
and
makeRow(row).apply(2)
are all equivalent.
makeRow(row) is of type List[String], each String representing one row. So effectively, you are picking character at index 2 from each row. That is why you are seeing 9 spaces and one 1 in your output.
def multiTable() = {
val tableSeq = // a sequence of row strings
for (row <- 1 to 10)
yield makeRow(row) {2}
tableSeq.mkString("\n")
}
is equivalent to applying a map on each row like
def multiTable() = {
val tableSeq = // a sequence of row strings
for (row <- 1 to 10)
yield makeRow(row)
tableSeq.map(_(2)).mkString("\n")
}

Base 36 counter without I or O

we have a requirement to make our serial numbers Base 36 (0-9,A-Z). My initial thought was store the counter in decimal and convert to hex only when required for display. This makes the counting simple, however there is another requirement to not use I or O because it'll be confused with 1 and 0 on the barcodes human readable portion. This makes it a bit of a nightmare.
Language is unimportant, but the counter itself will be held in SQL Server 2012+.
Anyone have any experiences with this problem?
Edit:
I've rewritten a method I found to test in C#. It allows any string of base characters to be passed in.
ie. string baseChars = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ";
It's not pretty but its a start!
private string GetCustomBase(int iValue, string baseChars)
{
int baseNum = baseChars.Length;
int value= iValue;
string result = "";
while( value > 0 )
{
result = baseChars[ 0 + (value % baseNum)] + result;
value = value / baseNum;
}
return result;
}
private int GetDecimal(string strValue, string baseChars)
{
int baseNum = baseChars.Length;
string strAmendedValue = strValue;
int iResult = 0;
//Each char one at a time (from right)
for (int i = 0; i < strValue.Length; i++)
{
string c = strValue.Substring(strValue.Length - i -1, 1);
int iPos = baseChars.IndexOf(c); //get actual value (0 = 0, A = 10 etc.)
int iPowerVal = (int)Math.Pow((double)baseNum, (double)(i));
iResult = iResult + (iPowerVal * iPos);
}
return iResult;
}
An implementation of the suggestion in the question comments. As language is unimportant, here's a Ruby version:
class Integer
def to_34_IO_shifted
to_s(34).upcase.tr("IJKLMNOPQRSTUVWX", "JKLMNPQRSTUVWXYZ")
end
end
class String
def from_34_IO_shifted
upcase.tr("JKLMNPQRSTUVWXYZIO", "IJKLMNOPQRSTUVWX10").to_i(34)
end
end
puts 170.times.map { |x| x.to_34_IO_shifted }.join(' ')
x = 73644
x34 = x.to_34_IO_shifted
x10 = x34.from_34_IO_shifted
puts "\n#{x} -> '#{x34}' -> #{x10}"
puts "'10' -> #{'10'.from_34_IO_shifted}"
puts "'IO' -> #{'IO'.from_34_IO_shifted}"
Output:
0 1 2 3 4 5 6 7 8 9 A B C D E F G H J K L M N P Q R S T U V W X Y Z 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 1G 1H 1J 1K 1L 1M 1N 1P 1Q 1R 1S 1T 1U 1V 1W 1X 1Y 1Z 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 2G 2H 2J 2K 2L 2M 2N 2P 2Q 2R 2S 2T 2U 2V 2W 2X 2Y 2Z 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 3G 3H 3J 3K 3L 3M 3N 3P 3Q 3R 3S 3T 3U 3V 3W 3X 3Y 3Z 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 4G 4H 4J 4K 4L 4M 4N 4P 4Q 4R 4S 4T 4U 4V 4W 4X 4Y 4Z
73644 -> '1VQ0' -> 73644
'10' -> 34
'IO' -> 34
EDIT: made it so that I and O are interpreted as 1 and 0, in case someone does misread it.

Scala how can I count the number of occurrences in a list

val list = List(1,2,4,2,4,7,3,2,4)
I want to implement it like this: list.count(2) (returns 3).
A somewhat cleaner version of one of the other answers is:
val s = Seq("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges")
s.groupBy(identity).mapValues(_.size)
giving a Map with a count for each item in the original sequence:
Map(banana -> 1, oranges -> 3, apple -> 3)
The question asks how to find the count of a specific item. With this approach, the solution would require mapping the desired element to its count value as follows:
s.groupBy(identity).mapValues(_.size)("apple")
scala collections do have count: list.count(_ == 2)
I had the same problem as Sharath Prabhal, and I got another (to me clearer) solution :
val s = Seq("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges")
s.groupBy(l => l).map(t => (t._1, t._2.length))
With as result :
Map(banana -> 1, oranges -> 3, apple -> 3)
list.groupBy(i=>i).mapValues(_.size)
gives
Map[Int, Int] = Map(1 -> 1, 2 -> 3, 7 -> 1, 3 -> 1, 4 -> 3)
Note that you can replace (i=>i) with built in identity function:
list.groupBy(identity).mapValues(_.size)
Starting Scala 2.13, the groupMapReduce method does that in one pass through the list:
// val seq = Seq("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges")
seq.groupMapReduce(identity)(_ => 1)(_ + _)
// immutable.Map[String,Int] = Map(banana -> 1, oranges -> 3, apple -> 3)
seq.groupMapReduce(identity)(_ => 1)(_ + _)("apple")
// Int = 3
This:
groups list elements (group part of groupMapReduce)
maps each grouped value occurrence to 1 (map part of groupMapReduce)
reduces values within a group of values (_ + _) by summing them (reduce part of groupMapReduce).
This is a one-pass version of what can be translated by:
seq.groupBy(identity).mapValues(_.map(_ => 1).reduce(_ + _))
val list = List(1, 2, 4, 2, 4, 7, 3, 2, 4)
// Using the provided count method this would yield the occurrences of each value in the list:
l map(x => l.count(_ == x))
List[Int] = List(1, 3, 3, 3, 3, 1, 1, 3, 3)
// This will yield a list of pairs where the first number is the number from the original list and the second number represents how often the first number occurs in the list:
l map(x => (x, l.count(_ == x)))
// outputs => List[(Int, Int)] = List((1,1), (2,3), (4,3), (2,3), (4,3), (7,1), (3,1), (2,3), (4,3))
I ran into the same problem but wanted to count multiple items in one go..
val s = Seq("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges")
s.foldLeft(Map.empty[String, Int]) { (m, x) => m + ((x, m.getOrElse(x, 0) + 1)) }
res1: scala.collection.immutable.Map[String,Int] = Map(apple -> 3, oranges -> 3, banana -> 1)
https://gist.github.com/sharathprabhal/6890475
If you want to use it like list.count(2) you have to implement it using an Implicit Class.
implicit class Count[T](list: List[T]) {
def count(n: T): Int = list.count(_ == n)
}
List(1,2,4,2,4,7,3,2,4).count(2) // returns 3
List(1,2,4,2,4,7,3,2,4).count(5) // returns 0
It is interesting to note that the map with default 0 value, intentionally designed for this case demonstrates the worst performance (and not as concise as groupBy)
type Word = String
type Sentence = Seq[Word]
type Occurrences = scala.collection.Map[Char, Int]
def woGrouped(w: Word): Occurrences = {
w.groupBy(c => c).map({case (c, list) => (c -> list.length)})
} //> woGrouped: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences
def woGetElse0Map(w: Word): Occurrences = {
val map = Map[Char, Int]()
w.foldLeft(map)((m, c) => m + (c -> (m.getOrElse(c, 0) + 1)) )
} //> woGetElse0Map: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences
def woDeflt0Map(w: Word): Occurrences = {
val map = Map[Char, Int]().withDefaultValue(0)
w.foldLeft(map)((m, c) => m + (c -> (m(c) + 1)) )
} //> woDeflt0Map: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences
def dfltHashMap(w: Word): Occurrences = {
val map = scala.collection.immutable.HashMap[Char, Int]().withDefaultValue(0)
w.foldLeft(map)((m, c) => m + (c -> (m(c) + 1)) )
} //> dfltHashMap: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences
def mmDef(w: Word): Occurrences = {
val map = scala.collection.mutable.Map[Char, Int]().withDefaultValue(0)
w.foldLeft(map)((m, c) => m += (c -> (m(c) + 1)) )
} //> mmDef: (w: forcomp.threadBug.Word)forcomp.threadBug.Occurrences
val functions = List("grp" -> woGrouped _, "mtbl" -> mmDef _, "else" -> woGetElse0Map _
, "dfl0" -> woDeflt0Map _, "hash" -> dfltHashMap _
) //> functions : List[(String, String => scala.collection.Map[Char,Int])] = Lis
//| t((grp,<function1>), (mtbl,<function1>), (else,<function1>), (dfl0,<functio
//| n1>), (hash,<function1>))
val len = 100 * 1000 //> len : Int = 100000
def test(len: Int) {
val data: String = scala.util.Random.alphanumeric.take(len).toList.mkString
val firstResult = functions.head._2(data)
def run(f: Word => Occurrences): Int = {
val time1 = System.currentTimeMillis()
val result= f(data)
val time2 = (System.currentTimeMillis() - time1)
assert(result.toSet == firstResult.toSet)
time2.toInt
}
def log(results: Seq[Int]) = {
((functions zip results) map {case ((title, _), r) => title + " " + r} mkString " , ")
}
var groupResults = List.fill(functions.length)(1)
val integrals = for (i <- (1 to 10)) yield {
val results = functions map (f => (1 to 33).foldLeft(0) ((acc,_) => run(f._2)))
println (log (results))
groupResults = (results zip groupResults) map {case (r, gr) => r + gr}
log(groupResults).toUpperCase
}
integrals foreach println
} //> test: (len: Int)Unit
test(len)
test(len * 2)
// GRP 14 , mtbl 11 , else 31 , dfl0 36 , hash 34
// GRP 91 , MTBL 111
println("Done")
def main(args: Array[String]) {
}
produces
grp 5 , mtbl 5 , else 13 , dfl0 17 , hash 17
grp 3 , mtbl 6 , else 14 , dfl0 16 , hash 16
grp 3 , mtbl 6 , else 13 , dfl0 17 , hash 15
grp 4 , mtbl 5 , else 13 , dfl0 15 , hash 16
grp 23 , mtbl 6 , else 14 , dfl0 15 , hash 16
grp 5 , mtbl 5 , else 13 , dfl0 16 , hash 17
grp 4 , mtbl 6 , else 13 , dfl0 16 , hash 16
grp 4 , mtbl 6 , else 13 , dfl0 17 , hash 15
grp 3 , mtbl 5 , else 14 , dfl0 16 , hash 16
grp 3 , mtbl 6 , else 14 , dfl0 16 , hash 16
GRP 5 , MTBL 5 , ELSE 13 , DFL0 17 , HASH 17
GRP 8 , MTBL 11 , ELSE 27 , DFL0 33 , HASH 33
GRP 11 , MTBL 17 , ELSE 40 , DFL0 50 , HASH 48
GRP 15 , MTBL 22 , ELSE 53 , DFL0 65 , HASH 64
GRP 38 , MTBL 28 , ELSE 67 , DFL0 80 , HASH 80
GRP 43 , MTBL 33 , ELSE 80 , DFL0 96 , HASH 97
GRP 47 , MTBL 39 , ELSE 93 , DFL0 112 , HASH 113
GRP 51 , MTBL 45 , ELSE 106 , DFL0 129 , HASH 128
GRP 54 , MTBL 50 , ELSE 120 , DFL0 145 , HASH 144
GRP 57 , MTBL 56 , ELSE 134 , DFL0 161 , HASH 160
grp 7 , mtbl 11 , else 28 , dfl0 31 , hash 31
grp 7 , mtbl 10 , else 28 , dfl0 32 , hash 31
grp 7 , mtbl 11 , else 28 , dfl0 31 , hash 32
grp 7 , mtbl 11 , else 28 , dfl0 31 , hash 33
grp 7 , mtbl 11 , else 28 , dfl0 32 , hash 31
grp 8 , mtbl 11 , else 28 , dfl0 31 , hash 33
grp 8 , mtbl 11 , else 29 , dfl0 38 , hash 35
grp 7 , mtbl 11 , else 28 , dfl0 32 , hash 33
grp 8 , mtbl 11 , else 32 , dfl0 35 , hash 41
grp 7 , mtbl 13 , else 28 , dfl0 33 , hash 35
GRP 7 , MTBL 11 , ELSE 28 , DFL0 31 , HASH 31
GRP 14 , MTBL 21 , ELSE 56 , DFL0 63 , HASH 62
GRP 21 , MTBL 32 , ELSE 84 , DFL0 94 , HASH 94
GRP 28 , MTBL 43 , ELSE 112 , DFL0 125 , HASH 127
GRP 35 , MTBL 54 , ELSE 140 , DFL0 157 , HASH 158
GRP 43 , MTBL 65 , ELSE 168 , DFL0 188 , HASH 191
GRP 51 , MTBL 76 , ELSE 197 , DFL0 226 , HASH 226
GRP 58 , MTBL 87 , ELSE 225 , DFL0 258 , HASH 259
GRP 66 , MTBL 98 , ELSE 257 , DFL0 293 , HASH 300
GRP 73 , MTBL 111 , ELSE 285 , DFL0 326 , HASH 335
Done
It is curious that most concise groupBy is faster than even mutable map!
Short answer:
import scalaz._, Scalaz._
xs.foldMap(x => Map(x -> 1))
Long answer:
Using Scalaz, given.
import scalaz._, Scalaz._
val xs = List('a, 'b, 'c, 'c, 'a, 'a, 'b, 'd)
then all of these (in the order of less simplified to more simplified)
xs.map(x => Map(x -> 1)).foldMap(identity)
xs.map(x => Map(x -> 1)).foldMap()
xs.map(x => Map(x -> 1)).suml
xs.map(_ -> 1).foldMap(Map(_))
xs.foldMap(x => Map(x -> 1))
yield
Map('b -> 2, 'a -> 3, 'c -> 2, 'd -> 1)
Try this, should work.
val list = List(1,2,4,2,4,7,3,2,4)
list.count(_==2)
It will return 3
I did not get the size of the list using length but rather size as one the answer above suggested it because of the issue reported here.
val list = List("apple", "oranges", "apple", "banana", "apple", "oranges", "oranges")
list.groupBy(x=>x).map(t => (t._1, t._2.size))
using cats
import cats.implicits._
"Alphabet".toLowerCase().map(c => Map(c -> 1)).toList.combineAll
"Alphabet".toLowerCase().map(c => Map(c -> 1)).toList.foldMap(identity)
Here is another option:
scala> val list = List(1,2,4,2,4,7,3,2,4)
list: List[Int] = List(1, 2, 4, 2, 4, 7, 3, 2, 4)
scala> list.groupBy(x => x) map { case (k,v) => k-> v.length }
res74: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1, 2 -> 3, 7 -> 1, 3 -> 1, 4 -> 3)
scala> val list = List(1,2,4,2,4,7,3,2,4)
list: List[Int] = List(1, 2, 4, 2, 4, 7, 3, 2, 4)
scala> println(list.filter(_ == 2).size)
3
Here is a pretty easy way to do it.
val data = List("it", "was", "the", "best", "of", "times", "it", "was",
"the", "worst", "of", "times")
data.foldLeft(Map[String,Int]().withDefaultValue(0)){
case (acc, letter) =>
acc + (letter -> (1 + acc(letter)))
}
// => Map(worst -> 1, best -> 1, it -> 2, was -> 2, times -> 2, of -> 2, the -> 2)
val words = Array("Mary", "had", "a", "little", "lamb", "its"
, "fleece", "was", "white", "as", "snow", "and", "everywhere"
, "that", "Mary", "went", "the", "lamb", "was", "sure", "to", "go")
words.groupBy(_.length)