Reduce Seq of String -> String to JObject with reduce(_ ~ _) ?

92 views
Skip to first unread message

Dave Briccetti

unread,
Oct 27, 2012, 3:45:58 PM10/27/12
to lif...@googlegroups.com
Hi all. This would be a handy thing to have work. Am I close?

scala> import net.liftweb.json._
scala> import net.liftweb.json.JsonDSL._

scala> val s = Seq("a"->"1", "b"->"2")
s: Seq[(java.lang.String, java.lang.String)] = List((a,1), (b,2))

scala> s.reduce(_ ~ _)
<console>:15: error: type mismatch;
 found   : net.liftweb.json.JsonAST.JObject
 required: (java.lang.String, java.lang.String)
              s.reduce(_ ~ _)
                         ^

Diego Medina

unread,
Oct 27, 2012, 8:04:40 PM10/27/12
to lif...@googlegroups.com
reduce cannot do what you want, but foldLeft can


import net.liftweb.json._
import net.liftweb.json.JsonDSL._
val s = Seq("a"->"1", "b"->"2")
List(1,2,3,4).foldLeft("")(_ + " " + _)
s.foldLeft()(_ ~ _ ) // Just need to figure out what to put inside the
first parenthesis, as an initial value

For example, with

List(1,2,3,4).foldLeft("")(_ + " " + _)

you go from a List of Ints, to a string : 1 2 3 4
but if you cannot reduce a List of strings to an Integer

Regards,

Diego
> --
> --
> Lift, the simply functional web framework: http://liftweb.net
> Code: http://github.com/lift
> Discussion: http://groups.google.com/group/liftweb
> Stuck? Help us help you:
> https://www.assembla.com/wiki/show/liftweb/Posting_example_code
>
>
>



--
Diego Medina
Lift/Scala Developer
di...@fmpwizard.com
http://www.fmpwizard.com

Diego Medina

unread,
Oct 27, 2012, 11:57:52 PM10/27/12
to lif...@googlegroups.com
maybe this is what you wanted:

scala> s.foldLeft(JObject(Nil))(_ ~ _)
res10: net.liftweb.json.JsonAST.JObject =
JObject(List(JField(a,JString(1)), JField(b,JString(2))))

scala>

Regards,

Diego

Antonio Salazar Cardozo

unread,
Oct 30, 2012, 1:21:27 AM10/30/12
to lif...@googlegroups.com
We use foldLeft with JObjects like this semi-frequently, both with _ ~ _ and _ merge _. The reason you need this is because a Tuple ~ a Tuple is not something that is defined. A JObject ~ a Tuple *is* defined. When Scala is trying to infer the types for reduce, it won't be able to figure out that you're trying to get a JObject out. foldLeft gives you an opportunity to specify the start value, which makes the return value the same, so that by the time you get to the _ ~ _ part, it already knows the first _ is a JObject, and does the rest correctly.

Hope that helps!
Thanks,
Antonio
Message has been deleted

Dave Briccetti

unread,
Oct 31, 2012, 3:48:22 AM10/31/12
to lif...@googlegroups.com
Thank you both. That should do what I need. But I’d like to understand this completely. Somehow this works:

("name", "value) ~ ("name2", "value2")

without any type “priming”.

Diego Medina

unread,
Oct 31, 2012, 10:28:37 PM10/31/12
to Lift
Hi Dave,

The way I understand reduce is, if you have something like a
List[Int], you can reduce to a value of type Int, but you cannot go
from List[Int] and reduce it to a String, as in:

scala> List(1, 2, 3).reduce(_ + " " + _)
<console>:8: error: type mismatch;
found : java.lang.String
required: Int
List(1, 2, 3).reduce(_ + " " + _)
^

scala> List(1, 2, 3).reduce(_ + _)
res1: Int = 6

scala>


so, for your case, you have a List[Tuple2[String]] and you want to
reduce them to a JObject, but reduce doesn't let you do that. Does
that clarify things?


("a" -> "2") ~ ("a" -> "2") works fine because we are not
restricted to how reduce works.

Diego

Dave Briccetti

unread,
Oct 31, 2012, 10:37:03 PM10/31/12
to lif...@googlegroups.com
Yes, that satisfies my curiosity for now. Thanks!

Antonio Salazar Cardozo

unread,
Nov 1, 2012, 5:33:32 PM11/1/12
to lif...@googlegroups.com
The reason why this is, by the way, is that reduce does not take a priming value. It combines starting with the first two elements of the collection, and then the result of that is the first parameter to the next iteration. As such, the first element of the collection has to be the same type as the result of the result of the computation, which basically restricts the types of the reduce operation to the same type as the collection itself (actually, the same type or any supertype, since we know any element of a collection will also be an instance of its supertype). Because folds take an initial value for the subsequent operation, they can have an arbitrary result type.

Hope that helps!
Thanks,
Antonio
Reply all
Reply to author
Forward
0 new messages