我编写了以下代码行来从数据帧中的列中过滤掉 NULL
df = df.where(col("colname").isNotNull)
这是正确的方法吗?
我还遇到了以下代码行来实现相同的结果:
df = df.filter($"colname".isNotNull)
现在我想了解的是 $ 运算符的用途是什么以及哪种方法更好? 我也可以写下面这样的东西吗?
df = df.filter(col("colname").isNotNull)
我对 Scala 和一般编程相当陌生,任何帮助将不胜感激!
最佳答案
有一个特殊的 Scala 类,名为 StringContext
。它用于实现各种字符串插值方法,例如
s"foo ${42}"
(结果为String
“foo 42”
),或
f"foo ${42}%04x"
(这会产生一个带有十六进制格式整数“foo 002a”
的String
)。
该机制实际上非常通用,允许您通过将 StringContext
隐式转换为您自己的包装类来定义各种不同的字符串插值机制。也就是说,如果您愿意,您可以定义如下所示的字符串插值机制:
myStringInterpolator"foo ${42}"
由于 $
只是一个普通标识符,因此您可以实现一个 StringContext
包装器,该包装器具有带签名的方法
def $(args: Any*): YourResultType
一旦此包装器处于隐式作用域中,您就可以使用 $
进行字符串插值,如下所示:
$"some string literal ${arg1} more text ${arg2} end"
这将使用 StringContext
构造包装器,其中包含 ["some stringliteral ", "more text ", "end"]
,然后调用您的 $
-带有 arg1
和 arg2
的方法。
例如,您可以定义一个字符串插值 $
将所有参数转换为整数并对它们求和:
implicit class MyDollarContext(s: StringContext) {
def $(args: Any*): Int = args.map(_.toString.toInt).sum
}
println($"I bought a coffee for ${30} and a snack for ${12}.")
这将打印 42
,它是 ${...}
大括号内所有数字的总和。
类似地,Apache Spark 使用隐式 StringToColumn
将 Strings
转换为 Spark ColumnName
的类。我不确定为什么要以这种方式实现,我猜他们想让列名看起来有点像 Perl 或 Bash 变量,并且为此使用了很多语法技巧。
关于java - Scala中$符号有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52554936/