Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 缺少值的列表上的算术运算_List_Scala_Math_Missing Data - Fatal编程技术网

List 缺少值的列表上的算术运算

List 缺少值的列表上的算术运算,list,scala,math,missing-data,List,Scala,Math,Missing Data,我试图在一个可能包含缺失值的列表上做一些算术运算。 到目前为止,我用选项[Int]表示我的列表: val mylist=List( Option(4), Option(8), None ) 通过这种表示,我可以轻松地在列表上应用函数(例如,乘以2): 然而,这看起来比它需要的更复杂,所以我想知道我是否遗漏了什么 而且,我也不知道如何写出像总和这样的东西。我想应该可以用一个(大的)reduce表达式 因此,我想知道: List[Option[Int]]是此用例的良好表示 mylist.map(

我试图在一个可能包含缺失值的列表上做一些算术运算。 到目前为止,我用选项[Int]表示我的列表:

val mylist=List( Option(4), Option(8), None )
通过这种表示,我可以轻松地在列表上应用函数(例如,乘以2):

然而,这看起来比它需要的更复杂,所以我想知道我是否遗漏了什么

而且,我也不知道如何写出像总和这样的东西。我想应该可以用一个(大的)reduce表达式

因此,我想知道:

  • List[Option[Int]]是此用例的良好表示
  • mylist.map(*2))
    是映射的最佳方式
  • 有一种简单的求和方法吗

嗯,这不是我自己使用过的模式,但是如果值可能“丢失”,那么使用
选项是合适的。但是
列表
可能不是。在
列表中
位置通常不是你应该依赖的,因为它不是随机访问。也许
向量
会更好,或者您需要想出一种更好的方法来建模您的问题,也就是说,不要将其作为缺少值的列表

您可以使用for表达式很好地处理
选项

for (o <- mylist; x <- o) yield x * 2
总而言之:

mylist.flatten.sum
  • List[Option[Int]]是此用例的良好表示
是否可以使用flatMap更早地将其展平?例如,如果您正在使用map创建此列表,则可以使用flatMap,并且不会缺少值。我的建议是,如果可能,甚至不要表示缺失的值。若您需要表示它们,那个么这个选项是理想的

  • mylist.map(*2))
    是映射的最佳方式
  • 有一种简单的求和方法吗
嵌套映射可能更可取。您还可以
foldLeft

foldLeft
如果您需要做除求和/积之外的事情,它也很有用

scala> val mylist=List( Option(4), Option(8), None )
mylist: List[Option[Int]] = List(Some(4), Some(8), None)

scala> mylist.foldLeft(0){
     |   case (acc, Some(i)) => acc + i 
     |   case (acc, _) => acc
     | }
res7: Int = 12

scala> (0 /: mylist) {
     |   case (acc, Some(i)) => acc + i 
     |   case (acc, _) => acc
     | }
res8: Int = 12

scala> (0 /: mylist) {
     |   case (acc, Some(i)) => acc - (i * 2)
     |   case (acc, _) => acc
     | }
res16: Int = -24
因此,我想知道:

List[Option[Int]]是此用例的良好表示

选项绝对是表示缺失值的首选方式。您还可以考虑将其更改为
列表[(Int,Int)]
,其中第一个元素表示原始列表中的位置,第二个元素表示值

mylist.map(*2))
是映射的最佳方式

在我看来,没有更短或更简洁的方式来表达这一点。(您有两个“级别”,这就是为什么您需要两个映射!)使用我建议的数据结构,这将变成
mylist.map(t=>(t._1,t._2*2))

有一种简单的求和方法吗


没有比om nom建议的更简单的方法了。对于我的数据结构,它将是mylist.map(u._2).sum

实现这一点的最通用和最简洁的方法是使用的半群类型类。这样,您就不局限于
List[Option[Int]]
,而是可以将相同的函数应用于
List[Int]

import scalaz._
import Scalaz._

object S {
  def double[A:Semigroup](l:List[A]) = l.map(x => x |+| x)
  def sum[A:Semigroup](l:List[A]) = l.reduce(_ |+| _)

  def main(a:Array[String]) {
    val l = List(Some(1), None, Some(2))
    val l2 = List(1,2)
    println(double(l))
    println(sum(l))
    println(double(l2))
    println(sum(l2))
  }

}
这张照片

List(Some(2), None, Some(4))
Some(3)
List(2, 4)
3

我不确定你想达到什么目的,但这似乎不是正确的方法。如果您需要确定“列表”中是否存在某个值,那么设置
可能更适合您的需要:

scala> val s = Set(4,8)
s: scala.collection.immutable.Set[Int] = Set(4, 8)

scala> s(4)
res0: Boolean = true

scala> s(5)
res1: Boolean = false

scala> s map (_ * 2)
res2: scala.collection.immutable.Set[Int] = Set(8, 16)

scala> s reduceLeft((a,b) => a+b)
res3: Int = 12
甚至更简单:

scala> s sum
res4: Int = 12
如果您需要更复杂的内容,并且列表中元素的索引很重要,您可以使用
映射
,其中键模拟索引,缺少的值可以映射到某个默认值:

scala> val m = Map(1 -> 4, 2 -> 8) withDefault(n => 0)
m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 4, 2 -> 8)

scala> m(1)
res5: Int = 4

scala> m(3)
res6: Int = 0

scala> m map {case (k,v) => (k,2*v)}
res7: scala.collection.immutable.Map[Int,Int] = Map(1 -> 8, 2 -> 16)

scala> m.foldLeft(0){case (sum,(_,v)) => sum+v}
res8: Int = 12
同样,我不确定你的需求是什么,但感觉你走错了方向……

选项
是一种我在使用前会三思而后行的类型。问问自己这是否真的有必要。可能有一些解决方案可以以更优雅的方式实现您正在尝试的目标。

要求和值,您可以使用mylist.Flatte.sum
将所有值都否决answers@drstevens发生的事情reported@drstevens我很好奇,为什么会有人这么做?(除非他们否决了所有答案,只有自己的答案除外?@Stevens博士,这很奇怪。我确实在这里投了赞成票,但我从来没有投过反对票,是的,理解和扁平化并没有持续下去,看起来@scala_新手想要拯救他们。如果没有,还有一种方法:flatMap them:
mylist.flatMap(*2)
实际上@om nom nom,flatMap不起作用(我有同样的想法),因为函数的参数类型必须是
Option[Int]
,在我的用例中,我有一系列对象。我需要对这些对象的属性进行统计,但是这些对象缺少(不同的)属性。我不确定我会如何使用这里的那些技术使用
映射[YourObjects,List[Attributes]]
怎么样?我不确定我是否理解你的建议。如果没有选项,如何将属性存储在列表中?如果你建议只保留现有属性的列表,我该如何区分它们(它们的索引不会固定)?我建议只保留现有属性的列表。假设您有一个属性trait:
MyAttribute
,那么,对于每个需要的属性,您都可以将该trait扩展为实际值。比如:
SomeAttribute或者,如果属性非常简单,并且创建一个超级特征是一个“过度解决方案”,那么您可以使用:
Map[YourObject,Map[Int,Attribute]]
scala> s sum
res4: Int = 12
scala> val m = Map(1 -> 4, 2 -> 8) withDefault(n => 0)
m: scala.collection.immutable.Map[Int,Int] = Map(1 -> 4, 2 -> 8)

scala> m(1)
res5: Int = 4

scala> m(3)
res6: Int = 0

scala> m map {case (k,v) => (k,2*v)}
res7: scala.collection.immutable.Map[Int,Int] = Map(1 -> 8, 2 -> 16)

scala> m.foldLeft(0){case (sum,(_,v)) => sum+v}
res8: Int = 12