ArrayIndexOutOfBounds访问RDD元素

时间:2017-12-29 10:41:50

标签: 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,

我需要做的是:

  1. 从2个RDD中读取2个文件的数据(我已经完成)

  2. 在dept文件中的日期列上应用过滤器并获取两个基于outout的文件 on null而非null值(我无法做到)

  3. 我能走多远:

    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

3 个答案:

答案 0 :(得分:1)

来自split(String regex, int limit)方法的描述:

  

limit 参数控制应用模式的次数,因此会影响结果数组的长度。如果限制n大于零,那么模式将最多应用n - 1次,数组的长度将不大于n,并且数组的最后一个条目将包含除最后一个匹配分隔符之外的所有输入。 如果n为非正,则模式将尽可能多地应用,并且数组可以具有任意长度。 如果n为零,则模式将被应用尽可能多次,数组可以具有任意长度,尾随空字符串将被丢弃

由于split(String regex)的工作原理就好像通过调用带有给定表达式和限制参数的双参数split方法,所以你的空字符串被丢弃了。

解决方案,也在纳塔利娅的answer中提到:

// collect each and every string
val cleanDept = loadDept.map(_.split(",", -1))  
// filter arrays with empty last string
val filledDateDept = cleanDept.filter(_.last.nonEmpty)  

答案 1 :(得分:0)

  1. 在访问其元素

    之前检查数组的大小
    function findLongest(array) {
      var biggestNum = 0;
    
      for(var i = 0; i < array.length; i++) {
      
        if(array[i].toString().length > biggestNum.toString().length) {
          biggestNum = array[i];
        }
        
      }
      
      return biggestNum;
    }
    
    console.log(findLongest([111, 1111, 5555, 10000, 1, 90000]));
  2. 您可以使用sc.textFile("/file/path/dept.txt") .map(_.split(",")) .filter(a => a.length > 3 && a(3) != null && !a(3).equals(""))

    对结果进行分组
    groupBy
  3. 这会按sc.textFile("/file/path/dept.txt") .map(_.split(",")) .groupBy(a => a.length > 3 && a(3) != null && !a(3).equals("")) 键对结果进行分组,在这种情况下,它会是groupBytrue

    false键将保留所有null并且不存在缓冲区中的结果。

    false键将所有非null结果保存在Buffer中。

    输出

    true

答案 2 :(得分:0)

拆分操作中的问题。

"ab,dfd,".split(",") --> Array(ab, dfd)
"ab,dfd,".split(",", -1) --> Array(ab, dfd, )

如果仅使用一个参数调用split,则使用默认限制。它等于0.

分裂的Java文档

  

limit参数控制模式的应用次数,因此会影响结果数组的长度。如果限制n大于零,则模式最多应用n - 1次,数组的长度不大于n,并且数组的最后一个条目将包含超出最后匹配的分隔符。如果n是非正数,那么模式将被应用尽可能多的次数,并且数组可以具有任何长度。如果n为零,那么模式将被应用尽可能多次,数组可以具有任何长度,并且尾随空字符串将被丢弃。

如您所见,如果为0,则为trailing empty strings will be discarded