Iterate the Array with in Array using dust.js - dust.js

[
[
"x1", "x2" ,
[
["n1", "n2"],["x3", "x4"],["x5", "x6"]
]
],
[
"y1", "y2"
],
[
"z1", "z2"
]
]
I want to access the x3 and x4 items , how to access with dustjs

It mostly depends on what you mean by "access", but here are some example templates that show you what happens if you use the special . reference, which in Dust means "the current iteration context"
{#.}
Item {.}
{/.}
Output:
Item x1,x2,n1,n2,x3,x4,x5,x6 Item y1,y2 Item z1,z2
By iterating one level into the current context, you see that the top-level array elements are iterated on. One step deeper:
{#.}{#.}
Item {.}
{/.}{/.}
Output:
Item x1 Item x2 Item n1,n2,x3,x4,x5,x6 Item y1 Item y2 Item z1 Item z2
Notice how the depth at which we traverse nested arrays increases the more levels of context you tell Dust to inspect. So for your above example, four levels will suffice:
{#.}{#.}{#.}{#.}
Item {.}
{/.}{/.}{/.}{/.}
Output:
Item x1 Item x2 Item n1 Item n2 Item x3 Item x4 Item x5 Item x6 Item y1 Item y2 Item z1 Item z2

Related

NetLogo: break out of nested foreach loop

I'm trying to break out of a nested foreach loop using 2 lists of sorted turtles.
But instead of just leaving the inner loop, netlogo breaks out of the whole procedure.
I have a code like the one below (this one is made up, but has exactly the same structure):
to do-something
let xturtles sort-by [ [a b] -> [birthday] of a > [birthday] of b ] turtles
;; construct an ordered set
foreach xturtles [ the-xturtle ->
ask the-xturtle [
let xage birthday
let yturtles sort-by [ [a b] -> [birthday] of a > [birthday] of b ] turtles with [birthday < xage]
;; construct a second ordered set
foreach yturtles [ the-yturtle ->
let breakout-condition? false
ask the-yturtle [
if (hidden? ) [
set breakout-condition? true
]
]
if breakout-condition? [ stop ]
]
]
]
end
However, when the stop condition is reached, netlogo breaks out of the whole procedure, instead of continuing with the outer loop (the xturtles loop)?
Is that the expected behavior? If so, what is a good practice in this case?
Thanks!
Felix
It looks even nesting the stop within an extra ask procedure in the same procedure doesn't help. However, if you need a quick fix I think you can replace the second foreach loop with a standalone procedure that contains the stop as a workaround. For example, this procedure follows a similar format to yours and the same problem comes up- as soon as stop is called the broader foreach is exited.
to nest-foreach-example
ca
crt 1
let xs [ 1 2 3 4 ]
let ys [ 1 2 3 4 ]
foreach xs [
x ->
foreach ys [
y ->
ask turtles [
if y > x [
stop
]
]
print word x y
]
]
end
This prints out 11.
However, if you make a custom procedure to take the place of your "y" foreach loop, it works (with or without the ask turtles):
to nest-foreach-example-turtles
ca
crt 1
let xs [ 1 2 3 4 ]
let ys [ 1 2 3 4 ]
foreach xs [
x ->
for-y x ys
]
end
to for-y [ x_ ys ]
foreach ys [
y ->
ask turtles [
if y > x_ [
stop
]
]
print word x_ y
]
end
Outputs:
11
21
22
31
32
33
41
42
43
44

How do I merge the content of SPSS variables from different columns

I want to create five new variable K1 K2 K3 K4 K5 where the table below will return the content for each in their order of entry as shown on Fig 2
SN ID1 ID2 ID3 ID4 ID5 IE1 IE2 IE3 IE4 IE5
1 a b c d e
2 b a f c k
Fig 2
SN K1 K2 K3 K4 K5
1 a b c d e
2 b a f c k
Here's a possible way to do it:
(first recreating your example data to demonstrate on:)
data list list/ SN (f1) ID1 to ID5 IE1 to IE5 (10a1).
begin data
1, "a", "b", "c", , , "d", "e", , ,
2, "b", "a", , "f", , "c", "k", , ,
end data.
This is your example data, now you can run the following syntax, which will yield the results you expected:
string K1 to K5 (a1).
vector K=K1 to K5.
compute #x=1.
do repeat id=ID1 to IE5.
do if id<>"".
compute K(#x)=id. /* correction made here .
compute #x=#x+1.
end if.
end repeat.

Netlogo: Using foreach to iterate over two lists filled with variables

This may be a beginner question, but after using the NetLogo Progamming Guide I'm unable to find a solution...
I am trying to iterate over a pair of lists and conditionally update the values based on a test condition.
This thread in a Netlogo Forum which gave me the hint to use the LIST primitives reporter but I still can't get the expected output.
Here is a simplified example which describes my problem.
Please note, that listA and listB are both filled with variables.
to test
let a1 1
let a2 5
let listA (list a1 a2)
let b1 6
let b2 3
let listB (list b1 b2)
(foreach (list listA) (list listb) [
[a b] -> ifelse a < b [set a "a"][set b "b"]])
show lista
show listb
end
;expected Output
;observer: [a 5]
;observer: [6 b]
Could someone give me a hint? What am I doing wrong?
Lists in NetLogo are immutable- you can't change the values quite like this approach. map might be more suitable for this:
to test2
let a1 1
let a2 5
let listA (list a1 a2)
let b1 6
let b2 3
let listB (list b1 b2)
show ( map [ [ a b ] ->
ifelse-value ( a < b ) [ "a" ] [ a ] ]
listA listB ;; pass the lists [ 1 5 ] and [ 6 3 ]
)
show ( map [ [ a b ] ->
ifelse-value ( a > b ) [ "b" ] [ b ] ]
listA listB ;; pass the lists [ 1 5 ] and [ 6 3 ]
)
end
Note that I think your expected output for lista should be ["a" 5] not ["a" 0]- is that correct?
If you'd like to do this with foreach to modify the original lists, I would create an index ( 0 to the length of the list ) to pass to replace-item:
to test3
let a1 1
let a2 5
let listA (list a1 a2)
let b1 6
let b2 3
let listB (list b1 b2)
let indexer ( range 0 length listA )
foreach indexer [ ind ->
let current_a item ind listA
let current_b item ind listB
ifelse current_a < current_b [
set listA replace-item ind listA "a"
] [
set listB replace-item ind listB "b"
]
]
print listA
print listB
end

NetLogo: histogram with list of strings

I just tried to create a histogram build upon a list of characters like this:
histogram [a c a c b c a c c c c c c a c c a c a c a a c c c a a b c b c]
But it doesn't show anything.
Is it just supposed to handle numbers or am I missing something?
You didnĀ“t use quotes in your histogram list, but I am assuming that you wanted to plot a list of strings like ["a" "b" "c" ...], right?
As far as I know, it is not possible to use categorical values (like strings) for a histogram in netlogo plots. This is also stated in the netlogo dictionary:
histogram [...] Any non-numeric values in the list are ignored. [...]
One way to solve this would be a conversion to a numeric list by just giving every string-character a specific number:
let m ["a" "c" "a" "c" "b" "c" "a" "a" "c" "c" "b" "b" "c" "c" "a" "a"]
let n [ ]
foreach m
[
if (? = "a") [set n lput 0 n]
if (? = "b") [set n lput 1 n]
if (? = "c") [set n lput 2 n]
;...
]
histogram n
histogram work as you said. It's not easy to help you with as little information about your code. For me the error can come from 2 ways :
the plot context definition need to be in bar (i.e image)
the x-range plot definition need to be defined
for the 2nd hypothese some thing like
set-plot-x-range 0 ( (max myliste) + 5)
histogram myliste
let maxbar modes myliste
let maxrange length filter [ ? = item 0 maxbar ] myliste
set-plot-y-range 0 1000
In the plot on code interface may work
If you choose the 2nd ways, you don't need tout defined the scale like on the screenshot

Process a stream of Tuples without mutability?

So I want a function that receives an array of Tuple<int,int> and returns the same type but with different values.
What I want to do is a function that returns this kind of values:
f( [1,10; 2,20; 3,40; 4,70] ) = [2,10; 3,20; 4,30]
So as you can see, the first number is basically unchanged (except the 1st item is not picked), but the last number is the substraction of the current number with the previous number (20 - 10 = 10, 40 - 20 = 20, ...).
I've tried to come up with an algorithm in F# that doesn't involve mutability (using an accumulator for the previous value would mean I need a mutable variable), but I can't figure out. Is this possible?
Using built-in functions. In this case, you can use Seq.pairwise. The function takes a sequence of inputs and produces a sequence of pairs containing the previous value and the current value. Once you have the pairs, you can use Seq.map to transform the pairs into the results - in your case, take the ID of the current value and subtract the previous value from the current value:
input
|> Seq.pairwise
|> Seq.map (fun ((pid, pval), (nid, nval)) -> nid, nval-pval)
Note that the result is a sequence (IEnumerable<T>) rather than a list - simply because the Seq module contains a few more (useful) functions. You could convert it back to list using List.ofSeq.
Using explicit recursion. If your task did not fit one of the common patterns that are covered by some of the built-in functions, then the answer would be to use recursion (which, in general, replaces mutation in the functional style).
For completeness, the recursive version would look like this (this is not perfect, because it is not tail-recursive so it might cause stack overflow, but it demonstrates the idea):
let rec f list =
match list with
| (pid, pval)::(((nid, nval)::_) as tail) ->
(nid, nval-pval)::(f tail)
| _ -> []
This takes a list and looks at the first two elements of the list (pid, pval) and (nid, nval). Then it calculates the new value based on the two elements in (nid, nval-pval) and then it recursively processes the rest of the list (tail), skipping over the first element. If the list has one or fewer elements (the second case), then nothing is returned.
The tail-recursive version could be written using the "accumulator" trick. Instead of writing newValue::(recursiveCall ...) we accumulate the newly produced values in a list kept as an argument and then reverse it:
let rec f list acc =
match list with
| (pid, pval)::(((nid, nval)::_) as tail) ->
f tail ((nid, nval-pval)::acc)
| _ -> List.rev acc
Now you just need to call the function using f input [] to initialize the accumulator.
> let values = [(1, 10); (2, 20); (3, 40); (4, 70)];;
val values : (int * int) list = [(1, 10); (2, 20); (3, 40); (4, 70)]
> values
|> Seq.pairwise
|> Seq.map (fun ((x1, y1), (x2, y2)) -> (x2, y2 - y1))
|> Seq.toList;;
val it : (int * int) list = [(2, 10); (3, 20); (4, 30)]
Seq.pairwise gives you each element in a sequence as a pair, except the first element, which is only available as the predecessor of the second element.
For example:
> values |> Seq.pairwise |> Seq.toList;;
val it : ((int * int) * (int * int)) list =
[((1, 10), (2, 20)); ((2, 20), (3, 40)); ((3, 40), (4, 70))]
Second, Seq.map maps each of these pairs of pairs by using the desired algorithm.
Notice that this uses lazy evaluation - I only used Seq.ToList at the end to make the output more readable.
BTW, you can alternatively write the map function like this:
Seq.map (fun ((_, y1), (x2, y2)) -> (x2, y2 - y1))
Notice that instead of x1 is replaced with _ because the value isn't used.
Mark and Tomas have given really good solutions for the specific problem. Your question had a statement I think warrants a third answer, though:
(using an accumulator for the previous value would mean I need a mutable variable)
But this is actually not true! List.fold exists exactly to help you process lists with accumulators in a functional way. Here is how it looks:
let f xs = List.fold (fun (y, ys) (d, x) -> x, (d, x-y) :: ys)
(snd (List.head xs), [])
(List.tail xs)
|> snd |> List.rev
The accumulator here is the argument (y, ys) to the fun ... in the first line. We can see how the accumulator updates to the right of the ->: we accumulate both the previous element of the list x, as well as the new list we're constructing (d, x-y)::xs. We'll get that list in reverse order, so we reverse it in the end with List.rev.
Incidentally, List.fold is tail-recursive.
Of course, Tomas and Mark's solutions using Seq.pairwise are much neater for your particular problem, and you'd definitely want to use one of those in practice.
Whenever we need to create a sequence from another sequence, where one element in the output is a function of its predecessors, scan (docs) comes in handy:
[1,10; 2,20; 3,40; 4,70]
|> List.scan (fun ((accA, accB), prevB) (elA, elB) -> ((elA, elB-prevB), elB)) ((0, 0), 0)
|> Seq.skip 2
|> Seq.map fst
yields:
[(2, 10); (3, 20); (4, 30)]

Resources