Scala 访问RDD元素时出现ArrayIndexOutOfBounds异常
我有一个文件如下:Scala 访问RDD元素时出现ArrayIndexOutOfBounds异常,scala,apache-spark,rdd,Scala,Apache Spark,Rdd,我有一个文件如下: dept.txt: 1,It,pune,2017-03-12 2,CS,delhi,2017-03-21 3,mech,mum, 4,fin,pune,2017-04-15 5,It,delhi, 我需要做的是: 从2 RDD中的2个文件读取数据(我已经完成了) 在dept文件中的日期列上应用筛选器,并基于 关于空值和非空值(我无法做到这一点) 我能进行到什么程度: val loadDept = sc.textFile("/path/to/file/dept.txt") v
dept.txt:
1,It,pune,2017-03-12
2,CS,delhi,2017-03-21
3,mech,mum,
4,fin,pune,2017-04-15
5,It,delhi,
我需要做的是:
val loadDept = sc.textFile("/path/to/file/dept.txt")
val cleanDept = loadDept.map(_.split(","))
val dateCol = cleanDept.filter(i => i(3) != "")
最后一行出现错误:
java.lang.ArrayIndexOutOfBoundsException:3
我知道,由于存在空字符串/null,我得到了一个越界异常(如果我错了,请纠正我),但是如何处理它呢
注意:我只需要在Scala中使用RDD
sc.textFile("/file/path/dept.txt")
.map(_.split(","))
.filter(a => a.length > 3 && a(3) != null && !a(3).equals(""))
groupBy
sc.textFile("/file/path/dept.txt")
.map(_.split(","))
.groupBy(a => a.length > 3 && a(3) != null && !a(3).equals(""))
groupBy
键对结果进行分组,在这种情况下,结果将是true
或false
false
键将在缓冲区中保存所有null和notexist结果
true
键将所有非空结果保存在缓冲区中
输出
(false,CompactBuffer([Ljava.lang.String;@5bef517c, [Ljava.lang.String;@51ec0ad3))
(true,CompactBuffer([Ljava.lang.String;@44a4871, [Ljava.lang.String;@16a375ad, [Ljava.lang.String;@37703dfd))
拆分操作中的问题
"ab,dfd,".split(",") --> Array(ab, dfd)
"ab,dfd,".split(",", -1) --> Array(ab, dfd, )
如果仅使用一个参数调用split,则使用默认限制。它等于0
用于拆分的Java文档
limit参数控制应用阵列的次数,因此会影响结果阵列的长度。如果限制n大于零,则模式最多应用n-1次,数组长度不大于n,数组的最后一个条目将包含最后一个匹配分隔符之外的所有输入。如果n为非正,则图案将被应用尽可能多的次数,并且阵列可以具有任意长度。如果n为零,则将尽可能多次应用该模式,数组可以有任何长度,并且将丢弃尾随的空字符串
如您所见,在0的情况下,所有尾随的空字符串都将被丢弃
根据方法说明:
limit参数控制应用阵列的次数,从而影响结果阵列的长度。如果限制n大于零,则模式最多应用n-1次,数组长度不大于n,数组的最后一个条目将包含最后一个匹配分隔符之外的所有输入如果n为非正则图案将被应用尽可能多的次数,并且阵列可以有任何长度如果n为零则模式将被应用尽可能多的次数,数组可以有任何长度,尾随的空字符串将被丢弃
由于使用给定表达式和限制参数0调用双参数split方法,因此空字符串被丢弃
Natalia的书中也提到了解决方案:
在访问阵列之前,首先检查长度elements@Saravana谢谢你的回复。如果看到dept.txt,则每行有4个值,用逗号分隔。所以我相信当我拆分时,我应该得到0,1,2,3个位置。因此试图得到i(3)。现在,我想,如果你检查第3行“3,mech,mum”,最后一个逗号后面没有空格或者什么都没有,直接回车。因此,我相信这个问题,但我不知道如何摆脱它,实现我想要的。请查看检查长度的答案,并根据索引3的元素对结果进行分组。这解决了问题。如果可能的话,请你解释一下-1。我从未见过或使用过这样的语句。长度为0的语句子字符串被丢弃是不正确的。第二个参数表示应用该模式拆分字符串的次数。@philantrovert谢谢,已通过copypasting javadoc for split修复
// collect each and every string
val cleanDept = loadDept.map(_.split(",", -1))
// filter arrays with empty last string
val filledDateDept = cleanDept.filter(_.last.nonEmpty)