ObservableBuffer giving IndexOutOfBounds in Scala - scala

I am mesmerized. The below code is giving me an indexoutofbound error. But if I were to delete the slashes enabling for(j <- i until tmpArray.length) it would work. I really do not understand why it is happening, and would appreciate an explanation.
for(i <- 0 until tmpArray.length)
{
// for(j <- i until tmpArray.length)
// {
if( date.getValue != null && tmpArray(i).date != date.getValue )
{
tmpArray.remove(i)
}
// }
}

You're modifying the array as you "iterate" over it.
You are actually iterating over the range 0 until tmpArray.length, which is calculated up front. At some point, you reduce the length of the array (or, I assume so, as I can't find remove on the Array class). But it's still going to continue the iteration up to whatever the last index was when you created the range.
When you uncomment the inner for block, you're making it recompute the range for each step of the outer for. And it just so happens that the j range will simply have nothing in it if i >= tmpArray.length. So it inadvertently guards against that failure.
This is very C-style (imperative) code. It looks like all you're trying to do is remove some items from an array. That's what filter is for.
val result = tmpArray.filter { d =>
if(date.getValue != null && d != date.getValue) false else true
}
This creates a new array (result) by passing an anonymous function to tmpArray.filter. It will pass each item in the array to your "predicate", and if it returns true, it'll keep that item in result, otherwise it will omit it.
You should note that I avoided saying "loop". Scala's for isn't for making loops. It's actually syntax sugar for calling methods like foreach and map. Google "scala for comprehensions" for more detail.
If you insist on creating a C-style loop using indexes and a loop variable, you'll want to use while, so that you can check if i < tmpArray.length each time.

Related

Forward reference extends over definition of variable in scala

I have a list. For all the numbers in odd position I want to make it 0. And for all the numbers in even position, I want to keep it as it is.I'm trying to do it via map in the following way.
Here's my code
def main(args: Array[String]) {
var l1 = List (1,2,3,4,5,6)
println(l1.map(f(_)))
var c = 0
def f(n:Int):Int =
{
if (c%2 == 0)
{c +=1
return n}
else
{c += 1
return 0}
I want the variable to keep track of the position. But as it seems,I can't forward reference 'c'.
I get the following error
scala forward reference extends over definition of variable c
I can't also declare 'c' inside the function, because it will never increment that way.
What should be the idea way to achieve what I am trying, with the help of map.
I have a list. For all the numbers in odd position I want to make it
0. And for all the numbers in even position, I want to keep it as it is.
Here's an elegant solution of this problem:
l1.zipWithIndex map { case (v, i) => if (i % 2 == 0) v else 0 }
As for the reason, why your code fails: you're trying to access variable c before its declaration in code. Here:
println(l1.map(f(_)))
var c = 0
Your function f is trying to access variable c, which is not declared yet. Reorder these two lines and it will work. But I'd recommend to stick with my initial approach.

Coffeescript iteration over array of objects does not compile as expected

I would like to perform an iteration over an array of objects. Instead of writing
for item in items
for k, v in item
# Do Something
I would like to do something similar to this
for k,v of item in items
# Do something
Which based on the compiled output is not supported:
var k, ref, ref1, v, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
ref1 = (ref = indexOf.call(items, item) >= 0) != null ? ref : [];
for (k in ref1) {
v = ref1[k];
# Do something
}
Is there any other comprehension-like operation through which I can perform this shortcut?
EDIT: I can refer to specific keys in the object by doing
for { k1, k2 }, i in items
# Do something
For the sake of the question, assume the keys are dynamic
No you can't. Following coffeescript's golden rule “it's just JavaScript”, consider looking at the source where a for loop gets translated. You will need two Javascript fors and you only can get one from a coffescript for (the for gets inserted in line 2079).
The javascript result you want to have is something like this:
for(_i…;…;…){
var _x = items[_i];
for(k in _x){
var v = _x[k]
…
}}
There are only two ways to get a javascript for loop (apart from the prewritten ones, like in class definitions): On “Range compilation”, which always gives a for(…;…;…) loop (which contructs an array inside a closure that will be returned) and for the for construct.
Your example to access single keys works because you are using some very special case of destructuring assignment. What you would need is a destructuring that extracts key-value pairs and there is none. If you look at the compiled example constructs like this get translated into a=items[i].a so such that there is no iteration. You even can omit the ,i:
for {a} in items
#iterate over the .a values of items
If your #Do something is just one line, you can put your fors on one line, but I personally think it doesn't increase the readability.
console.log [k,v] for k,v of i for i in items

Strange behavior in coffeescript for loop

I'm trying to iterate over array in CoffeeScript but there is some kind of strange behavior.
For example look on this code:
kapa = [1]
for i in kapa
console.log 't'
kapa.push 1
I expect that this code produce an infinite sequence of 't' symbols in console. But in reality it prints only one 't'.
What is the logic behind this behavior?
And how can I achieve expected behavior?
Explanation:
elements= [1]
for i in elements
proccess(element)
if someCond
newElement = ...
element.push(newElement) #
I want to achieve behavior when all newElements will be processed
The reason it only prints it out once is because that coffeescript compiles to this JS:
var i, kapa, _i, _len;
kapa = [1];
for (_i = 0, _len = kapa.length; _i < _len; _i++) {
i = kapa[_i];
console.log('t');
kapa.push(1);
}
So it calculates the length of the array in the beginning and doesn't get updated when you kapa.push(1). I would say this is expected behavior and moreover, modifying an array while you are iterating over it sounds like a bad idea. In other languages like Java, you would get an Exception if you tried to do that.
If you really want it to print infinite t and push 1 onto the array every time, you would need an infinite loop:
kapa = [1]
while true
console.log( 't' )
kapa.push( 1 )
(but thats obviously discouraged and I'm not sure why you would want that behavior)
UPDATE
Based on the updated question, you could use the array as a queue-like structure
elements= [1]
while nextElem = elements.shift()
proccess(nextElem)
if someCond
newElement = ...
elements.push(newElement)
Given your added explanation, maybe you are using your array as a queue:
elements= [1]
while elements.length
proccess(elements.shift())
if someCond
newElement = ...
element.push(newElement)
Notice the use of a while loop (whose end condition is evaluated at each iteration), and elements.shift that removes the first element of the queue.

Scala return does not return

There is some misunderstanding between me and Scala
0 or 1?
object Fun extends App {
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) { // when this is true
return 1 // and we are about to return 1, the code goes to the next line
}
foo(list.tail, count + 1) // I know I do not use "return here" ...
count
}
val result = foo( List(1,2,3) )
println ( result ) // 0
}
Why does it print 0?
Why does recursion work even without "return"
(when it is in the middle of function, but not in the end)?
Why doesn't it return 1? when I use "return" explicitly?
--- EDIT:
It will work if I use return here "return foo(list.tail, count + 1)'.
Bu it does NOT explain (for me) why "return 1" does not work above.
If you read my full explanation below then the answers to your three questions should all be clear, but here's a short, explicit summary for everyone's convenience:
Why does it print 0? This is because the method call was returning count, which had a default value of 0—so it returns 0 and you print 0. If you called it with count=5 then it would print 5 instead. (See the example using println below.)
Why does recursion work even without "return" (when it is in the middle of function, but not in the end)? You're making a recursive call, so the recursion happens, but you weren't returning the result of the recursive call.
Why doesn't it return 1? when I use "return" explicitly? It does, but only in the case when list is empty. If list is non-empty then it returns count instead. (Again, see the example using println below.)
Here's a quote from Programming in Scala by Odersky (the first edition is available online):
The recommended style for methods is in fact to avoid having explicit, and especially multiple, return statements. Instead, think of each method as an expression that yields one value, which is returned. This philosophy will encourage you to make methods quite small, to factor larger methods into multiple smaller ones. On the other hand, design choices depend on the design context, and Scala makes it easy to write methods that have multiple, explicit returns if that's what you desire. [link]
In Scala you very rarely use the return keyword, but instead take advantage that everything in an expression to propagate the return value back up to the top-level expression of the method, and that result is then used as the return value. You can think of return as something more like break or goto, which disrupts the normal control flow and might make your code harder to reason about.
Scala doesn't have statements like Java, but instead everything is an expression, meaning that everything returns a value. That's one of the reasons why Scala has Unit instead of void—because even things that would have been void in Java need to return a value in Scala. Here are a few examples about how expressions work that are relevant to your code:
Things that are expressions in Java act the same in Scala. That means the result of 1+1 is 2, and the result of x.y() is the return value of the method call.
Java has if statements, but Scala has if expressions. This means that the Scala if/else construct acts more like the Java ternary operator. Therefore, if (x) y else z is equivalent to x ? y : z in Java. A lone if like you used is the same as if (x) y else Unit.
A code block in Java is a statement made up of a group of statements, but in Scala it's an expression made up of a group of expressions. A code block's result is the result of the last expression in the block. Therefore, the result of { o.a(); o.b(); o.c() } is whatever o.c() returned. You can make similar constructs with the comma operator in C/C++: (o.a(), o.b(), o.c()). Java doesn't really have anything like this.
The return keyword breaks the normal control flow in an expression, causing the current method to immediately return the given value. You can think of it kind of like throwing an exception, both because it's an exception to the normal control flow, and because (like the throw keyword) the resulting expression has type Nothing. The Nothing type is used to indicate an expression that never returns a value, and thus can essentially be ignored during type inference. Here's simple example showing that return has the result type of Nothing:
def f(x: Int): Int = {
val nothing: Nothing = { return x }
throw new RuntimeException("Can't reach here.")
}
Based on all that, we can look at your method and see what's going on:
def foo(list:List[Int], count:Int = 0): Int = {
// This block (started by the curly brace on the previous line
// is the top-level expression of this method, therefore its result
// will be used as the result/return value of this method.
if (list.isEmpty) {
return 1 // explicit return (yuck)
}
foo(list.tail, count + 1) // recursive call
count // last statement in block is the result
}
Now you should be able to see that count is being used as the result of your method, except in the case when you break the normal control flow by using return. You can see that the return is working because foo(List(), 5) returns 1. In contrast, foo(List(0), 5) returns 5 because it's using the result of the block, count, as the return value. You can see this clearly if you try it:
println(foo(List())) // prints 1 because list is empty
println(foo(List(), 5)) // prints 1 because list is empty
println(foo(List(0))) // prints 0 because count is 0 (default)
println(foo(List(0), 5)) // prints 5 because count is 5
You should restructure your method so that the value that the body is an expression, and the return value is just the result of that expression. It looks like you're trying to write a method that returns the number of items in the list. If that's the case, this is how I'd change it:
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) count
else foo(list.tail, count + 1)
}
When written this way, in the base case (list is empty) it returns the current item count, otherwise it returns the result of the recursive call on the list's tail with count+1.
If you really want it to always return 1 you can change it to if (list.isEmpty) 1 instead, and it will always return 1 because the base case will always return 1.
You're returning the value of count from the first call (that is, 0), not the value from the recursive call of foo.
To be more precise, in you code, you don't use the returned value of the recursive call to foo.
Here is how you can fix it:
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) {
1
} else {
foo(list.tail, count + 1)
}
}
This way, you get 1.
By the way, don't use return. It doesn't do always what you would expect.
In Scala, a function return implicitly the last value. You don't need to explicitly write return.
Your return works, just not the way you expect because you're ignoring its value. If you were to pass an empty list, you'd get 1 as you expect.
Because you're not passing an empty list, your original code works like this:
foo called with List of 3 elements and count 0 (call this recursion 1)
list is not empty, so we don't get into the block with return
we recursively enter foo, now with 2 elements and count 1 (recursion level 2)
list is not empty, so we don't get into the block with return
we recursively enter foo, now with 1 element and count 2 (recursion level 3)
list is not empty, so we don't get into the block with return
we now enter foo with no elements and count 3 (recursion level 4)
we enter the block with return and return 1
we're back to recursion level 3. The result of the call to foo from which we just came back in neither assigned nor returned, so it's ignored. We proceed to the next line and return count, which is the same value that was passed in, 2
the same thing happens on recursion levels 2 and 1 - we ignore the return value of foo and instead return the original count
the value of count on the recursion level 1 was 0, which is the end result
The fact that you do not have a return in front of foo(list.tail, count + 1) means that, after you return from the recursion, execution is falling through and returning count. Since 0 is passed as a default value for count, once you return from all of the recursed calls, your function is returning the original value of count.
You can see this happening if you add the following println to your code:
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) { // when this is true
return 1 // and we are about to return 1, the code goes to the next line
}
foo(list.tail, count + 1) // I know I do not use "return here" ...
println ("returned from foo " + count)
count
}
To fix this you should add a return in front of foo(list.tail.....).
you return count in your program which is a constant and is initialized with 0, so that is what you are returning at the top level of your recursion.

Best way to create generic/method consistency for sort.data.frame?

I've finally decided to put the sort.data.frame method that's floating around the internet into an R package. It just gets requested too much to be left to an ad hoc method of distribution.
However, it's written with arguments that make it incompatible with the generic sort function:
sort(x,decreasing,...)
sort.data.frame(form,dat)
If I change sort.data.frame to take decreasing as an argument as in sort.data.frame(form,decreasing,dat) and discard decreasing, then it loses its simplicity because you'll always have to specify dat= and can't really use positional arguments. If I add it to the end as in sort.data.frame(form,dat,decreasing), then the order doesn't match with the generic function. If I hope that decreasing gets caught up in the dots `sort.data.frame(form,dat,...), then when using position-based matching I believe the generic function will assign the second position to decreasing and it will get discarded. What's the best way to harmonize these two functions?
The full function is:
# Sort a data frame
sort.data.frame <- function(form,dat){
# Author: Kevin Wright
# http://tolstoy.newcastle.edu.au/R/help/04/09/4300.html
# Some ideas from Andy Liaw
# http://tolstoy.newcastle.edu.au/R/help/04/07/1076.html
# Use + for ascending, - for decending.
# Sorting is left to right in the formula
# Useage is either of the following:
# sort.data.frame(~Block-Variety,Oats)
# sort.data.frame(Oats,~-Variety+Block)
# If dat is the formula, then switch form and dat
if(inherits(dat,"formula")){
f=dat
dat=form
form=f
}
if(form[[1]] != "~") {
stop("Formula must be one-sided.")
}
# Make the formula into character and remove spaces
formc <- as.character(form[2])
formc <- gsub(" ","",formc)
# If the first character is not + or -, add +
if(!is.element(substring(formc,1,1),c("+","-"))) {
formc <- paste("+",formc,sep="")
}
# Extract the variables from the formula
vars <- unlist(strsplit(formc, "[\\+\\-]"))
vars <- vars[vars!=""] # Remove spurious "" terms
# Build a list of arguments to pass to "order" function
calllist <- list()
pos=1 # Position of + or -
for(i in 1:length(vars)){
varsign <- substring(formc,pos,pos)
pos <- pos+1+nchar(vars[i])
if(is.factor(dat[,vars[i]])){
if(varsign=="-")
calllist[[i]] <- -rank(dat[,vars[i]])
else
calllist[[i]] <- rank(dat[,vars[i]])
}
else {
if(varsign=="-")
calllist[[i]] <- -dat[,vars[i]]
else
calllist[[i]] <- dat[,vars[i]]
}
}
dat[do.call("order",calllist),]
}
Example:
library(datasets)
sort.data.frame(~len+dose,ToothGrowth)
Use the arrange function in plyr. It allows you to individually pick which variables should be in ascending and descending order:
arrange(ToothGrowth, len, dose)
arrange(ToothGrowth, desc(len), dose)
arrange(ToothGrowth, len, desc(dose))
arrange(ToothGrowth, desc(len), desc(dose))
It also has an elegant implementation:
arrange <- function (df, ...) {
ord <- eval(substitute(order(...)), df, parent.frame())
unrowname(df[ord, ])
}
And desc is just an ordinary function:
desc <- function (x) -xtfrm(x)
Reading the help for xtfrm is highly recommended if you're writing this sort of function.
There are a few problems there. sort.data.frame needs to have the same arguments as the generic, so at a minimum it needs to be
sort.data.frame(x, decreasing = FALSE, ...) {
....
}
To have dispatch work, the first argument needs to be the object dispatched on. So I would start with:
sort.data.frame(x, decreasing = FALSE, formula = ~ ., ...) {
....
}
where x is your dat, formula is your form, and we provide a default for formula to include everything. (I haven't studied your code in detail to see exactly what form represents.)
Of course, you don't need to specify decreasing in the call, so:
sort(ToothGrowth, formula = ~ len + dose)
would be how to call the function using the above specifications.
Otherwise, if you don't want sort.data.frame to be an S3 generic, call it something else and then you are free to have whatever arguments you want.
I agree with #Gavin that x must come first. I'd put the decreasing parameter after the formula though - since it probably isn't used that much, and hardly ever as a positional argument.
The formula argument would be used much more and therefore should be the second argument. I also strongly agree with #Gavin that it should be called formula, and not form.
sort.data.frame(x, formula = ~ ., decreasing = FALSE, ...) {
...
}
You might want to extend the decreasing argument to allow a logical vector where each TRUE/FALSE value corresponds to one column in the formula:
d <- data.frame(A=1:10, B=10:1)
sort(d, ~ A+B, decreasing=c(A=TRUE, B=FALSE)) # sort by decreasing A, increasing B