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.
Related
I'm new to julia, but not so new on Dash; I'm trying to build my first app with Dash for julia, but I can't seem to make a pattern matching callback work properly. Here's the part of the code that's giving me troubles:
callback!(
app,
Output((type= "filter_", index= ALL), "options"),
Input("inputs", "data"),
State((type= "filter_", index= ALL), "value"),
) do inputs, filters
list_outs = []
list_vals = []
for i in 1:length(filters)
push!(list_outs, [(label= input, value= input) for input in inputs])
end
return list_outs
end
What I'm trying to do here is to use the available inputs of the data set, already stored in "inputs", to set the filters' options, creating as many sets of options as there are dropdowns.
The problem here is, I guess, in the format of the output I'm returning: it says "Invalid number of output values for {"index":["ALL"],"type":"filter_"}.options. Expected 3, got 1"
Sadly, I found nothing of use about how to use pattern matching callbacks with julia; I tried passing the output both as an array and as a tuple, but to no avail.
Any help is welcomed, thank you all!
This is the error related to the fact that if the result is a single Output, the callback output is automatically represented as an array of what is returned for uniform further processing. I.e., in your case, as [list_outs]. The fact that the Output with the match pattern is also treated as a single one is my bug, I added the issue and try to fix it in the near future.
Right now you can work around this problem by using Output as an array:
using Dash
using DashHtmlComponents
using DashCoreComponents
app = dash()
app.layout = html_div() do
dcc_input(id = "input", value = "A,B,C"),
dcc_dropdown(id = (type="filter_", index = 1)),
dcc_dropdown(id = (type="filter_", index = 2)),
dcc_dropdown(id = (type="filter_", index = 3)),
dcc_dropdown(id = (type="filter_", index = 4))
end
callback!(
app,
[Output((type= "filter_", index= ALL), "options")], #This is multiple output in explicitly form
Input("input", "value"),
State((type= "filter_", index= ALL), "value"),
) do input, filters
inputs = split(input, ",")
list_outs = []
list_vals = []
for i in 1:length(filters)
push!(list_outs, [(label= input, value= input) for input in inputs])
end
return [list_outs] # Accordingly, we return the result inside an additional array
end
run_server(app, debug = true)
I have been playing with Pony arrays to understand Pony better, and wanted to write the map function for any arrays.
I am talking about something like the standard map function most languages have nowadays for converting elements of collections, as in Clojure:
(map #(+ 1 %) [1 2 3]) ; => [2 3 4]
But I want it to actually modify the given array, not return a new one.
My current attempt so far runs into many errors due to capabilities:
// array is "iso" so I can give it to another actor and change it
let my_array: Array[U64] iso = [1; 2; 3; 4]
// other actor tries to recover arrays as "box" just to call pairs() on it
let a = recover box my_array end // ERROR: can't recover to this capability
for (i, item) in a.pairs() do
// TODO set item at i to some other mapped value
try my_array.update(i, fun(item))? end
end
Anyone knows how this can be done
Alright, took me a while, but I was able to get things working.
Here's my basic understanding of what's going on (please correct me if I'm wrong)!
The first step was to understand that we need to use aliases to change the capabilities of a variable in Pony.
So, in order to make an iso variable useable as a box, one must alias it by basically, consuming it into another variable:
let a: Array[U64] ref = consume array // array is "iso"
for (i, item) in a.pairs() do
try a.update(i, item + n)? end
end
This works!!
One more problem I had was that I couldn't do much with the resulting Array[U64] ref. Can't pass it to anyone, for example.
So I wrapped the whole thing into a recover block in order to end up with the same array, but as a val (immutable reference to the array) which is more useful as I can send it to other actors:
let result = recover val
let a: Array[U64] ref = consume array
for (i, item) in a.pairs() do
try a.update(i, item + n)? end
end
a
end
Now I can send result to anyone!
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.
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
Although I know about splats, still I can't quite grasp the last line from the following code:
class Borrowable extends Decorator
constructor: (#libraryItem) ->
removeBorrower: (borrower) ->
#borrowers[t..t] = [] if ( t = #borrowers.indexOf(borrower) ) > -1
Btw, this code was copied from https://github.com/aksharp/Design-Patterns/blob/master/CoffeeScript/Decorator.coffee
Im assuming this is Destructuring Assignment, still I can't quite get my head around what's it's happening behind the scenes.
Could you help clarify this?
Let's have a closer look at the last line:
#borrowers[t..t] = [] if ( t = #borrowers.indexOf(borrower) ) > -1
I'm not sure if this form counts as Destructuring Assignment, probably it is.
First, it calls #borrowers.indexOf(borrower) to check that borrower is present inside of the #borrowers array and to get it's index.
It's conventional to use borrower in #borrowers form instead of #borrowers.indexOf(borrower) > -1, but in this case we need index of an element as well.
If borrower is present in #borrowers, it gets the part of the #borrowers array between indexes t and t
#borrowers[t..t]
which is the [borrower], and assigns it to the empty array [], thus removing the borrower from #borrowers array.
Here is js-like equivalent of this assignment:
#borrowers.splice t, 1