3
\$\begingroup\$

I have been attempting to learn Scala lately and so have produced a couple of different sorting algorithms to build up my basics.

I think I have been lucky with the methods returning exactly what I have wanted, but for MergeSort I have implemented recursive methods that could return one of two different values and could logically be placed into two different values of the same type (as I believe Scala does)

In order to get my program to sort properly I have put a temp variable in order to grab the returning value and then be able to use it.

Is there a better way to return the values that will not need me to create these temporary values or should I have been doing something else?


Example:

def merge(left: ArrayBuffer[Int], right: ArrayBuffer[Int]): ArrayBuffer[Int]

returns an ArrayBuffer, how does the scala language figure out which value to put the returned value into or does it need a variable on the returning end to capture the value that is being returned?

merge(left, right)

This does nothing while,

var tempResult = merge(left, right)

Solves the problem.

Am I doing something wrong in the first instance (due to my experience with single parameter methods returning to the proper variable), or is this the standard way to return the values, by returning to a variable?


MergeSortClass.scala

import scala.collection.mutable.ArrayBuffer
class MergeSortClass {

def mergeSort(array: ArrayBuffer[Int]): ArrayBuffer[Int] = {

if (array.size <= 1) {

  array

} else {

  var left = ArrayBuffer[Int]()
  var right = ArrayBuffer[Int]()
  var middle = array.size / 2

  for (i <- 0 until middle) {

    left += array(i)

  }

  for (i <- middle until array.size) {

    right += array(i)

  }

//-->>>TheseValues Below

  var leftTemp = mergeSort(left);
  var rightTemp = mergeSort(right);

  var result = merge(leftTemp, rightTemp)

  result

}

}

def merge(left: ArrayBuffer[Int], right: ArrayBuffer[Int]): ArrayBuffer[Int] = {

var result = ArrayBuffer[Int]()

while (left.size > 0 || right.size > 0) {

  if (left.size > 0 && right.size > 0) {

    if (left(0) <= right(0)) {

      result += left(0)
      left.remove(0)

    } else {

      result += right(0)
      right.remove(0)

    }
  } else if (left.size > 0) {

    result += left(0)
    left.remove(0)

  } else if (right.size > 0) {

    result += right(0)
    right.remove(0)

  }

}

result

 }

}

MergeSortObject.scala

import scala.collection.mutable.ArrayBuffer
object MergeSortObject {

  def main(args: Array[String]): Unit = {

val array = ArrayBuffer(10, 5, 15, 25, 7, 11, 17, 35, 34, 16)

for (i <- 0 to array.length - 1) {

  print(array(i))

  if (i == array.length - 1) {

  } else {

    print(", ")

  }

}

println()

var ms = new MergeSortClass()

//-->>>TheseValues Below

var temp = ms.mergeSort(array)
//ms.test(array) (not shown here)

for (i <- 0 to temp.length - 1) {

  print(temp(i))

  if (i == temp.length - 1) {

  } else {

    print(", ")

  }

}

}

}
\$\endgroup\$
  • 1
    \$\begingroup\$ I don't understand what you mean with "temporary values". Can you highlight the lines you mean and explain more how the code should look in the end? \$\endgroup\$ – kiritsuku Apr 27 '14 at 12:39
  • \$\begingroup\$ I think he is talking about using array buffers to simulate sequential data streams. This is bound to be inefficient. @BoydyBoydy If you want a reasonably efficient sort, give up on array buffers and use simple arrays, passing indices to identify subarrays in the usual manner. See for example the scala-lang.org/old/node/57.html quicksort code on the Scala web site. \$\endgroup\$ – Gene Apr 27 '14 at 21:35
  • \$\begingroup\$ @sschaef What I was talking about was how scala differentiates between what values to return and how it returns those values. In order to get my Merge Sort to work I had to create values that would receive the returned values and not just pass the value into an already created variable but into a new one. Is there an easier way to grab the values that are being returned or is that how I should get all of my returned values(by creating a new variable and keeping the value in that variable)? Also I do not care about the efficiency as I do about being able to maintain/OO design code later! \$\endgroup\$ – BoydyBoydy Apr 27 '14 at 23:27
  • \$\begingroup\$ I have also updated my question, with broken lines so that you can see where the "temporary values" are. \$\endgroup\$ – BoydyBoydy Apr 27 '14 at 23:30
2
\$\begingroup\$

The expression merge(x,y) will always return a value. val r = merge(x,y) stores the value so that you can use it again.

You could write your code

var leftTemp = mergeSort(left);
var rightTemp = mergeSort(right);

var result = merge(leftTemp, rightTemp)

result

as

merge(mergeSort(left),mergeSort(right))

It is a matter of preference if you wish to use leftTemp and rightTemp like this, but the use of result, and then returning it on the next line is not idiomatic Scala.

You must assign values to an identifier when you want to use them more than once (as you do with temp in your final example). But as I said above you may want to do this for other reasons such as readability and keeping down line lengths.

\$\endgroup\$
  • \$\begingroup\$ Thankyou, all I really needed was a simple answer and I got that. Sorry can't upvote. \$\endgroup\$ – BoydyBoydy May 1 '14 at 0:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.