字符或字符串-> Scala 中的Unicode 值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11165635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Char or String -> Unicode value in Scala?
提问by adelbertc
So I'm working through a few of the exercises in "Scala for the Impatient" and one of them is:
所以我正在完成“不耐烦的 Scala”中的一些练习,其中之一是:
Write a forloop for computing the product of the Unicode codes of all letters in a string. For example, the product of the characters in "Hello" is 9415087488 L.
编写一个for循环来计算字符串中所有字母的 Unicode 代码的乘积。例如,“你好”中的字符的乘积是 9415087488 L。
The next problem is to do the same, but without a forloop - it hints that we should check StringOpsin Scaladoc.
下一个问题是做同样的事情,但没有for循环——它暗示我们应该检查StringOpsScaladoc。
I checked the RichCharand StringOpssection in Scaladoc, and perhaps I'm misreading or looking in the wrong places, but I can't find anything that gets me to match their output. I've thus far tried:
我检查了Scaladoc 中的RichCharandStringOps部分,也许我读错了或找错了地方,但我找不到任何让我匹配他们输出的东西。到目前为止,我已经尝试过:
scala> x.foldLeft(1)(_ * _.toInt)
res0: Int = 825152896
scala> x.foldLeft(1)(_ * _.getNumericValue)
res5: Int = 2518992
scala> x.foldLeft(1)(_ * _.intValue())
res6: Int = 825152896
scala> var x = 1
x: Int = 1
scala> for (c <- "Hello") x *= c.toInt
scala> x
res12: Int = 825152896
Which does not match their output.
这与他们的输出不匹配。
How do I do this, in both the forand non-forway?
我该如何做到这一点,无论for是非for方式还是非方式?
Thanks!
谢谢!
采纳答案by Brian Hsu
When you do x.foldLeft(1)(_ * _.toInt), the result type will be inference to an Int, but 9415087488 is too large for an Intto store it.
当您这样做时x.foldLeft(1)(_ * _.toInt),结果类型将是对 an 的推断Int,但 9415087488 太大而Int无法存储它。
So you need to tell Scala using Longto store it.
所以你需要告诉 Scala usingLong来存储它。
scala> val x = "Hello"
x: java.lang.String = Hello
scala> x.foldLeft(1L)(_ * _.toInt)
res1: Long = 9415087488
scala> var x: Long = 1
x: Long = 1
scala> for (c <- "Hello") x *= c.toInt
scala> x
res7: Long = 9415087488
回答by seth2810
If you convert each RichChar of String .toLong it's also works. For example, this:
如果您转换 String 的每个 RichChar .toLong 它也可以。例如,这个:
str.map (_.toLong).product- work's fine and without foldLeft or cycles
str.map (_.toLong).product- 工作正常,没有 foldLeft 或循环
This is cyclic variant:
这是循环变体:
def product(str: String): Long = {
var prod: Long = 1
for (ch <- str) prod *= ch
prod
}
回答by Andrey Kudryavtsev
There's a special "product" method in StringOps which multiplies up the elements of the collection. But it uses Char type because the string consist of char elements. And we're having overflow while trying to compute "Hello".product. So I converted the string to Vector of Long Unicode values by "Hello".map(_.toLong) and computed the product of its elements by this code:
StringOps 中有一个特殊的“产品”方法,可以将集合的元素相乘。但它使用 Char 类型,因为字符串由 char 元素组成。我们在尝试计算“Hello”.product 时出现溢出。因此,我通过 "Hello".map(_.toLong) 将字符串转换为长 Unicode 值的向量,并通过以下代码计算其元素的乘积:
scala> "Hello".map(_.toLong).product
res79: Long = 9415087488
回答by Rihad
Here's another way:
这是另一种方式:
scala> (for (c <- "Hello") yield c.toLong).product
res36: Long = 9415087488
回答by emote_control
The most straightforward way I've found to do this is:
我发现最直接的方法是:
"Hello".foldLeft(1L)((x:Long, y:Char) => x*y)
The method takes two parameters: a Long and a delegate function that takes a Long and a Char and returns a Long. You can pass an anonymous function in directly like this, or you can define the function elsewhere and pass it in, like so:
该方法接受两个参数:一个 Long 和一个委托函数,该函数接受一个 Long 和一个 Char 并返回一个 Long。您可以像这样直接传入匿名函数,也可以在其他地方定义该函数并将其传入,如下所示:
def multiply(x:Long, y:Char) = {
x*y
}
"Hello".foldLeft(1L)(multiply)
回答by Andris
I'd think the conversion to intermediate map is inefficient because in this case the collection is iterated twice: once to create map of longs and second time to multiply all elements. Unnecessary temporary collection of Long's also is not needed. I give my vote to
我认为转换为中间映射是低效的,因为在这种情况下,集合被迭代了两次:一次是创建 longs 的映射,第二次是将所有元素相乘。也不需要对 Long 进行不必要的临时收集。我投票给
"Hello".foldLeft(1L)(_ * _)
回答by Vzzarr
The exercise required to don't use for loop, so I've gone recursive:
不需要使用 for 循环的练习,所以我递归了:
def unicode_rec(s: String): Int =
if(s == "") 1
else s.head.toInt * unicode_rec(s.tail)
回答by R Sun
So here we have in bunch together :)
所以在这里我们有一堆:)
// one way
val longs = for (c <- str) yield c.toLong
println(longs.product)
// 2nd way
println(str.foldLeft(1L)(_ * _.toInt))
// 3rd way
var x = 1L
for (c <- str) yield x *= c.toInt
println(x)
// 4th way
var product = 1L
for (c <- str) {
product *= c.toInt
}
println(product)
// 5th way
println(str.map(_.toLong).product)
// 6th way
println(str.foldLeft(1L)(_ * _))
// 7th way
println(str.map(_.toLong).reduceLeft(_ * _)) // my IDE warns `Replace reduce with product`
// 8th way
println(str.map(_.toLong).scanLeft(1L)(_ * _).last)
// 9th way
println(str.map(_.toLong).reduce((x, y) => (x * y))) // my IDE warns `Replace reduce with product`
// using recursion
def exercise9(str: String): Long = {
var product = str.head.toLong
if (str.tail.length > 0) {
product *= exercise9(str.tail)
}
product
}
回答by jcadcell
Another variant:
另一种变体:
"Hello".aggregate(1L)({(prod,ch) => prod * ch.toLong}, {(p1,p2)=>p1*p2})

