Is it possible to interleave two arrays/lists in Openscad - openscad

I have 2 arrays and I'd like to interleave their values.
For example
Interleave([[1,2],[2,2],[3,2]], [[3,1],[4,1],[5,1]]); // Should yield [[1,2],[3,1],[2,2],[4,1],[3,2],[5,1]]
However I can't get something like this to work.
function Interleave(Set1,Set2) =[for(x=[0:len(Set1)-1]) Set1[x], Set2[x]];

The comma is not doing what you expect. It's separating 2 list entries, the first one is the for generatator and the 2nd one is just Set2[x] which is undefined as the x belongs to the for.
You can see what's going on when using just a string for the second part:
function Interleave(Set1,Set2) =[for(x=[0:len(Set1)-1]) Set1[x], "test"];
// ECHO: [[1, 2], [2, 2], [3, 2], "test"]
To get the interleaved result, you can generate a list with 2 entries for each interation and unwrap that using each
function Interleave(Set1,Set2) =[for(x=[0:1:len(Set1)-1]) each [Set1[x], Set2[x]]];
Also note the ..:1:.. step size, this ensures sane behavior in case Set1 is empty. The start:end range behaves differently for backward compatibility reasons.

Related

Specifying only a single index of a 1D array in a data file

Consider the following toy model, call it foo.mzn:
int: n = 2;
array[1..n] of var 0..2: vert;
constraint vert[1] != vert[2];
solve satisfy;
The documentation (Listing 2.2.3) shows an example where the data file specifies the entire array. That is, you could do:
./minizinc -D "vert=[0,1]" foo.mzn
However, what if I only want to specify one index of the array? It feels reasonable to be able to do:
./minizinc -D "vert[1]=0" foo.mzn
but this results in
Error: syntax error, unexpected =, expecting ':'
Is it possible to specify only a single index of an array in a data file? An alternative is to do away without an array, but perhaps this is not necessary.
One way is to define the second element as an unknown/unassigned value (_), e.g.
./minizinc -D "vert[0,_]" foo.mzn
This yields two solutions:
vert: [0, 1]
vert: [0, 2]

Finding all occurences of a string within a cell array (itself part of a struc)

I have the following structure
dataDens =
dens: [1x172 double]
level: {1x172 cell}
raga: {1x172 cell}
within which dataDens.raga consists of (reducing the number of columns below for simplicity)
Columns 1 through 3
'Multani' 'Tori' 'Tori'
I'd like to find the indices at which 'Tori' appears (that is, [2 3] for the example above). However, all of the commands I tried (below) either give an error, or return blank outputs. I think it's probably just a matter of adding/removing a curly bracket somewhere, or using some conversion; but I am at my wit's end, and hope someone can help clarify
indices = find(strcmp([dataDens.raga{:}], {'Tori'}))
indices = ismember('Tori', dataDens.raga)
[if,where] = ismember('Tori', dataDens.raga)
The issue had indeed to do with brackets. [dataDens.raga{:}] will result in concatenation of the character arrays, like so:
>> [dataDens.raga{:}]
ans =
'MultaniToriTori'
Using strcmp to compare this to 'Tori' will result in false, since there is no exact match. You can however compare the entire cell using strcmp, which will then return a boolean array, in which find can be used to obtain the indices of true entries:
indices = find(strcmp(data, {'Tori'}))
Alternatively, ismember would also work, but using ismember('Tori', dataDens.raga) you are checking whether 'Tori' is in dataDens.raga, not the other way around. Changing this to
ismember(dataDens.raga, 'Tori')
would again give you a boolean array, and find will obtain the indices you are looking for.

Implementing the map function for a Pony array

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!

Setting property in array of Matlab objects

I am working with arrays of structs and objects in Matlab. I want to set properties for all the members of a certain array as fast as possible.
For the problem of setting a certain struct field, I reached a solution that involves using arrayfun and setfield. The following works like a charm:
myStru.id = 0;
myStru.name = 'blah';
arrayStru = repmat(myStru,10,1); % Array of 10 elements. All of them have id=0
arrayStru = cell2mat( arrayfun( #(x,y)setfield(x,'id',y), arrayStru, (1:10)', 'UniformOutput', false ) ); % ids ranging from 1 to 10 :D
The problem is that, for objects, this does not work. I understand that setfield is for structures, so I have tried some other alternatives. The most excruciating error pops out when I try the following:
arrayfun( #(x,y) eval(['x.id=y;']), arrayOfObjects, arrayOfValues, 'UniformOutput', false );
(The class is a very simple one, which accepts empty constructor and has a real public property called 'id'). It results in:
Error using setFieldOfStructArray>#(x,y)eval(['x.id=y;']) (line 17)
Error: The expression to the left of the equals sign is not a valid target for an
assignment.
ALTHOUGH if I put a breakpoint in that line, it seems that the expression can be executed with the expected effects.
My two (three) questions:
Why does the above solution fail? How can I get that to work?
My final goal is to set properties fast and simple in arrays of objects. Which is the best technique for this?
(Note: I can write loops, but I always feel itchy when I have to do that :P)
I think the problem may be that your propety may be readonly because setfield works also for classes.
Anyway there is some alternative, if your class inherit from hgsetget you can use set instead of setfield.
You can also use
subsasgn(x,struct('type','.','subs','id'),y)
instead of
setfield(x,'id',y)
If can use cell of values, which will be automatically interpreted as struct array
>> s = struct('a', num2cell(1:10)', 'b', 's')
s =
10x1 struct array with fields:
a
b
>> [s.a]
ans =
1 2 3 4 5 6 7 8 9 10
>> [s.b]
ans =
ssssssssss

returning multiple dissimilar data structures from R function in PL/R

I have been looking at various discussions here on SO and other places, and the general consensus seems that if one is returning multiple non-similar data structures from an R function, they are best returned as a list(a, b) and then accessed by the indexes 0 and 1 and so on. Except, when using an R function via PL/R inside a Perl program, the R list function flattens the list, and also stringifies even the numbers. For example
my $res = $sth->fetchrow_arrayref;
# now, $res is a single, flattened, stringified list
# even though the R function was supposed to return
# list([1, "foo", 3], [2, "bar"])
#
# instead, $res looks like c(\"1\", \""foo"\", \"3\", \"2\", \""bar"\")
# or some such nonsense
Using a data.frame doesn't work because the two arrays being returned are not symmetrical, and the function croaks.
So, how do I return a single data structure from an R function that is made up of an arbitrary set of nested data structures, and still be able to access each individual bundle from Perl as simply $res->[0], $res->[1] or $res->{'employees'}, $res->{'pets'}? update: I am looking for an R equiv of Perl's [[1, "foo", 3], [2, "bar"]] or even [[1, "foo", 3], {a => 2, b => "bar"}]
addendum: The main thrust of my question is how to return multiple dissimilar data structures from a PL/R function. However, the stringification, as noted above, and secondary, is also problematic because I convert the data to JSON, and all those extra quotes just add to useless data transferred between the server and the user.
I think you have a few problems here. The first is you can't just return an array in this case because it won't pass PostgreSQL's array checks (arrays must be symmetric, all of the same type, etc). Remember that if you are calling PL/R from PL/Perl across a query interface, PostgreSQL type constraints are going to be an issue.
You have a couple of options.
You could return setof text[], with one data type per row.
you could return some sort of structured data using structures PostgreSQL understands, like:
CREATE TYPE ab AS (
a text,
b text
);
CREATE TYPE r_retval AS (
labels text[],
my_ab ab
);
This would allow you to return something like:
{labels => [1, "foo", 3], ab => {a => 'foo', b => 'bar'} }
But at any rate you have to put it into a data structure that the PostgreSQL planner can understand and that is what I think is missing in your example.