How can I create an interface for an array that accepts both numbers and strings?
Since inside the function [1,'1'], ['1','1'],[1,1] are equivalent (they are joined inside as '1.1'), I can't seem to satisfy the compiler. It gets me TS2087: Could not select overload for 'call' expression.
works for fn([1,1]); and fn(['1','1']); but not mixed values.
It's not possible. I suggest to use any[]:
function fn(arr: any[]) {
alert(JSON.stringify(arr));
}
fn([1, 1]);
fn(['1', '1']);
fn(['1', 1]);
Related
Consider the arbitrary function:
function myFunc_ = myFunc(firstInput, secondInput)
myFunc_ = firstInput * secondInput;
end
Now imagine I want to map the above function to an array for the first input firstInput, while the second input secondInput is constant. For example, something like:
firstVariable = linspace(0., 1.);
plot(firstVariable, map(myFunc, [firstVariable , 0.1]))
where 0.1 is an arbitrary scalar value for the secondInput and firstVariable array is an arbitrary array for the firstInput.
I have looked into the arrayfun() function. However, I don't know how to include the constant variable. Plus it seems like the syntax between MATLAB and Octave are different, or maybe I'm mistaken. It is important for me to have a cross-compatible code that I can share with colleagues.
Assuming in the original function you were multiplying two scalars and you want to vectorise, then
function myFunc_ = myFunc(firstInput, secondInput)
myFunc_ = firstInput .* secondInput;
end
should work just fine.
Then plot it directly:
plot( firstVariable, myFunc(firstVariable , 0.1) )
I'm afraid the arbitrary examples given in the original question were too simplified and as a result, they do not represent the actual issue I'm facing with my code. But I did manage to find the right syntax that works inside Octave:
plot(firstVariable, arrayfun(#(tempVariable) myFunc(tempVariable, 0.1), firstVariable))
basically the
#(tempVariable) myFunc(tempVariable, 0.1)
creates what is so-called an anonymous function and the
arrayfun(<function>, <array>)
maps the function over the given array.
I've been stuck with this for a while and I couldn't find something similar asked previously (or I have failed in doing so)
My situation is fairly simple: I have a cell array of objects. They are all the same object and I have a get function for this kind of object which is: get (obj, attr), where obj is the object in question and attr is a integer from 1-6. Depending on the number the get function returns the corresponding attribute.
I would like to obtain all of my "position" attributes from all my objects which are in the corresponding cell array (this would be attr = 2). I know that cellfun performs a function on all cells, but the question is, how do I use my get function here for all my objects, taking into account that the function is get (obj, attr) ?
Thanks in advance
Firstly, by using get as a custom function you are shadowing the built-in get function - this is bad practise!
With this in mind, and to avoid confusion with the built-in get function which has similar syntax, I'm going to use getattr as a stand-in for your custom function which accpets an object and an integer 1 to 6.
pos = cellfun( #(obj) getattr( obj, 2 ), myCellOfObjects, 'uni', 0 );
By specifying 'uni', 0, the output doesn't have to be scalar and will be put into a cell array. This is useful when, for example, you have a multi-element array for your position.
This is equivalent to the following loop:
pos = cell( numel(myCellOfObjects), 1 );
for ii = 1:numel(pos)
pos{ii} = getattr( myCellOfObjects{ii}, 2 );
end
If ever in doubt about cellfun or arrayfun, just write a loop first - they are essentially the same but more concise.
There is a trick to this some are unaware of: you can pass multiple arguments to cellfun like this:
cellfun(#(obj,attr) get(obj,attr), {obj1,obj2},{attr1,attr2},'uni',0)
if you want to get one attribute of the cellarray (instead of providing an attribute for every object in the cellarray), then you can simply use this
cellfun(#(x) getattr(x,attr),obj,'uni',0)
put into anonymous function for convenience:
get_attr = #(obj,attr) cellfun(#(x) getattr(x,attr),obj,'uni',0)
%use:
get_attr(obj_in_cellarray,'myattribute')
%returns cell array of object attributes
I haven't run any of these functions since you didn't provide any example data / code. Please test and feedback.
I want to splice a list of arguments to pass to a function. For a vector I know that I can use num2cell and call the cell with curly braces (see this question), but in my case the list I want to splice originally has structs and I need to access one of their attributes. For example:
austen = struct('ids', ids, 'matrix', matrix);
% ... more structs defined here
authors = [austen, dickens, melville, twain];
% the function call I want to do is something like
tmp = num2cell(authors);
% myFunction defined using varargin
[a,b] = myFunction(tmp{:}.ids);
The example above does not work because Matlab expected ONE output from the curly braces and it's receiving 4, one for each author. I also tried defining my list of arguments as a cell array in the first place
indexes = {austen.ids, dickens.ids, melville.ids, twain.ids};
[a,b] = myFunction(indexes{:});
but the problem with this is that myFunction is taking the union and intersection of the vectors ids and I get the following error:
Error using vertcat
The following error occurred converting from double to struct:
Conversion to struct from double is not possible.
Error in union>unionR2012a (line 192)
c = unique([a;b],order);
Error in union (line 89)
[varargout{1:nlhs}] = unionR2012a(varargin{:});
What is the correct way for doing this? The problem is that I will have tens of authors and I don't want to pass al of them to myFunction by hand.
As #kedarps rightly pointed out I need to use struct2cell instead of num2cell. The following code does the trick
tmp = struct2cell(authors);
[a, b] = myFunction(tmp{1,:,:}); %ids is the first entry of the structs
I had never heard about struct2cell before! It doesn't even show up in the See also of help num2cell! It would be amazing to have an apropos function like Julia's....
I have a function in Matlab:
function [runs,balls]=batting(form,team_flag,weather_flag)
form is a 1x13 array of doubles. The flags are just boolean. runs,balls are just scalars. The function above does some complex mathematical simulation to arrive at its output values. Now i write a wrapper :
function [runs,balls]=wrapper1(form)
[runs,balls]=batting(form,false,false);
Then I write another wrapper:
function runs_vector=wrapper2(form_vector)
for i=1:size(form_vector,1)
form_cell{i}=form_vector(i,:);
end
runs_vector=cellfun(#wrapper1, form_cell)';
It must be evident as to what i am trying to achieve. I am trying to exploit the behavior of cellfun for my custom-defined function batting. The flag arguments need to be set to false here but in general they are varied in the project of which this is part of. So i could not disappear the flag inputs to the batting function without writing an intermediate wrapper,i.e. wrapper1. My question is if there is a less ugly or more smart way of doing this?
You can eliminate wrapper1 by creating an anonymous function that reduces batting to two arguments:
runs_vector = cellfun(#(form) batting(form, false, false), form_cell)';
In addition, the loop can be replaced by num2cell like so:
form_cell = num2cell(form_vector, 2);
Combining these two gives us
function runs_vector = wrapper2(form_vector)
form_cell = num2cell(form_vector, 2);
runs_vector = cellfun(#(form) batting(form, false, false), form_cell)';
I am trying to create an array where each element is an empty array.
I have tried this:
var result = Array.fill[Array[Int]](Array.empty[Int])
After looking here How to create and use a multi-dimensional array in Scala?, I also tried this:
var result = Array.ofDim[Array[Int]](Array.empty[Int])
However, none of these work.
How can I create an array of empty arrays?
You are misunderstanding Array.ofDim here. It creates a multidimensional array given the dimensions and the type of value to hold.
To create an array of 100 arrays, each of which is empty (0 elements) and would hold Ints, you need only to specify those dimensions as parameters to the ofDim function.
val result = Array.ofDim[Int](100, 0)
Array.fill takes two params: The first is the length, the second the value to fill the array with, more precisely the second parameter is an element computation that will be invoked multiple times to obtain the array elements (Thanks to #alexey-romanov for pointing this out). However, in your case it results always in the same value, the empty array.
Array.fill[Array[Int]](length)(Array.empty)
Consider also Array.tabulate as follows,
val result = Array.tabulate(100)(_ => Array[Int]())
where the lambda function is applied 100 times and for each it delivers an empty array.