【问题标题】:Idiomatic Scala way to filter void values from list从列表中过滤 void 值的惯用 Scala 方法
【发布时间】:2015-04-28 21:44:36
【问题描述】:

我有这样的代码:

val mylist = (1,2,3)
val filteredList: List[Int] = mylist.map { num =>
   if (num < 3) num
}

所以我希望过滤列表包含 (1,2)。但是,在此之后,filteredList 的类型是 List[Any],而不是 List[Int]。如何删除 void/null/??值使其成为真正的整数列表?我尝试添加一个 else null 子句,然后从过滤列表中过滤掉 null 值,但它看起来不像是好的 Scala 风格......

【问题讨论】:

  • mylist.filter(_ &lt; 3)
  • 最短的格式是mylist.filter(3&gt;)

标签: scala


【解决方案1】:

假设myList 实际上是List(1, 2, 3) 而不是元组(1, 2, 3)

您应该使用filter 而不是map。您不想在 map 中放置一个 if 语句(或者即使通常是 if/else)。在这种情况下,它返回Unit,因为else 是编译器的filled in with Unit

也就是说,编译器会将你的代码变成:

val filteredList: List[Int] = mylist.map { num =>
   if (num < 3) num else ()
}

这意味着你实际上拥有

List(1, 2, Unit) // List[Any]

改为使用:

myList.filter(_ < 3)

或长格式:

myList.filter(num => num < 3)

(与 cmets 相关)您还可以使用collect 使用模式匹配一​​步过滤和映射。

myList.collect { case num if(num < 3) =>
   num // or do something with num to return a different type
}

【讨论】:

  • 啊,是的,对不起,我正在概括我的问题,并按照我的意图制作了一个元组而不是一个列表。如果在我的示例中,如果 (num
  • 我不太清楚你的意思。
  • 对不起。在我的实际用例中(这是一个巨大的概括),我想使用 num 作为参数来初始化一个类的实例,但前提是它小于 3。因此,mylist 和过滤列表应该是 List[MyObject] 类型。因此,如果我将过滤器语句移到最后,我将创建所有实例,然后只使用一个小子集。我宁愿一开始就不要创建所有实例。
  • 我明白了,所以你可以先filter,然后mapMyObject。您也可以使用collect 一步完成,但这与原来的问题有些不同。
【解决方案2】:

好吧,你想使用filter 而不是map

val filteredList = mylist.filter(num => num < 3)

或缩写:

val filteredList = myList.filter(_ < 3)

【讨论】:

    【解决方案3】:

    mylistTuple3,而不是您提到的List。如果myList 声明为这样val mylist = List(1,2,3),那么您可以轻松过滤它并使用filter 取回List[Int]

    val mylist = List(1,2,3)
    
    mylist.filter(num => num < 3)
    res0: List[Int] = List(1,2)
    

    【讨论】:

    • 啊,是的,对不起,我正在概括我的问题,并按照我的意图制作了一个元组而不是一个列表。如果在我的示例中,如果 (num
    猜你喜欢
    • 2015-03-09
    • 2016-07-02
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 2018-07-08
    相关资源
    最近更新 更多