字符或字符串-> 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 04:16:55  来源:igfitidea点击:

Char or String -> Unicode value in Scala?

scalaunicode

提问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})