0

Is there any way to convert a nested arrayBuffer to a nested array in scala ? I tried using the toArray function, but it did not convert the nested arrayBuffers

I have an array buffer of type Any and following is my sample nested

ArrayBuffer(
ArrayBuffer(ArrayBuffer(ArrayBuffer(1, b), 5)))
Hazzard
  • 11
  • 8
  • what have you done so far? can you show the example? – koiralo Jun 14 '17 at 13:17
  • `I have an array buffer of type Any ` This is probably an XY (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) question. You don't want to do that. Please explain a bit about what you're trying to do. – The Archetypal Paul Jun 15 '17 at 17:15
  • I want to write a nested arraybuffer to a dataframe. So for that I need to convert the arraybuffer to a nested seq so that I can pass it to a spark row – Hazzard Jun 16 '17 at 06:09
  • Here's the code I'm trying to use. def convert(a: Any): Array[Any] = a match { case ArrayBuffer(head @ ArrayBuffer(_*), tail @ ArrayBuffer(_*)) => Array(Row.fromSeq(convert(head)), Row.fromSeq(convert(tail))) case ArrayBuffer(inner @ ArrayBuffer(_*)) => Array(Row.fromSeq(convert(inner))) case ArrayBuffer(head @ ArrayBuffer(_*), tail @ _*) => (Row.fromSeq(convert(head)) +: tail).toArray case arr @ ArrayBuffer(_*) => Row(arr.toArray).toSeq.toArray } @TheArchetypalPaul – Hazzard Jun 16 '17 at 08:50
  • Edit the question. But I'm not asking how you are trying to convert it, I'm asking why you think you need an array buffer of type Any in the first place. It's almost never a good idea to try to work with Any. – The Archetypal Paul Jun 16 '17 at 10:07
  • Because I have a nested ArrayBuffer whose size is not fixed. Hence, I am using ArrayBuffer of type any – Hazzard Jun 16 '17 at 10:28
  • That's not enough explanation (there's no problem having arraybuffers of arraybuffers of different lengths). The problem in your example is not the nested arraybuffers, it's the 5. If you changed it to ArrayBuffer(5) then you stop getting Any. I doubt you really need arraybuffers containing elements of different types. You need a better-matched data structure. – The Archetypal Paul Jun 16 '17 at 13:38
  • The datatypes of the entries in the array buffer are not predefined. There can be a string, int, double, etc. Hence, I am using any @TheArchetypalPaul – Hazzard Jun 23 '17 at 05:57
  • You are still not explaining why. But I give up. If you don't want to to use a datastructure that allows strong typing - and it is always possible to do that - iyou will have a difficult time as you are finding out. Data structures of Any are never a good idea – The Archetypal Paul Jun 23 '17 at 06:02
  • Well I don't know what else to use when you don't know the datatype. I wanted the function to accept data irrespective of the type. – Hazzard Jun 23 '17 at 06:18

2 Answers2

1

The code below works for your specific test case. It converts nested ArrayBuffers that are the first element of the enclosing ArrayBuffer:

def convert(a: Any): Array[Any] = a match {
  case ArrayBuffer(inner @ ArrayBuffer(_*)) => Array(convert(inner))
  case ArrayBuffer(head @ ArrayBuffer(_*), tail @ _*) => (convert(head) +: tail).toArray
  case arr @ ArrayBuffer(_*) => arr.toArray
}

val result = convert(ArrayBuffer(ArrayBuffer(ArrayBuffer(ArrayBuffer(1, "b"), 5))))
// result is Array(Array(Array(Array(1, "b"), 5)))

Perhaps the above will help you come up with a more general solution.

Jeffrey Chung
  • 19,319
  • 8
  • 34
  • 54
0

I have created a generic function to convert arraybuffer to array.This takes care of nested arrayBuffers also

def convert(a: ArrayBuffer[Any]): Array[Any] = {

  val checkExistance = (x:ArrayBuffer[Any]) => x.zipWithIndex.collect{ case(x,y) if x.isInstanceOf[ArrayBuffer[Any]] => y}.toArray
  //filter(x => x.isInstanceOf[ArrayBuffer[Any]])
  val arr = checkExistance(a)
  for(i <- arr) {
    //if (a(i).isInstanceOf[ArrayBuffer[Any]]) {
    val m = a(i).asInstanceOf[ArrayBuffer[Any]]
    if(checkExistance(m).length > 0) {
      a.update(i,(convert(m)).toArray)
    }
    else {
      val n = m.toArray
      a.update(i,n)
    }
  }
  a.toArray
}
Hazzard
  • 11
  • 8