Can I simplify this array diff code, using some coffeescript syntax sugar I didn't know about?
first = [{id:1},{id:2},{id:3},{id:4},{id:5}]
second = [{id:3},{id:4},{id:5},{id:6},{id:7}]
first = first.filter (first_element) ->
second = second.filter (second_element) ->
if first_element.id == second_element.id
first_element.remove = second_element.remove = true
return !second_element.remove?
return !first_element.remove?
console.log(first.concat second) # [{id:1},{id:2},{id:6},{id:7}]
This one translates to exactly the same javascript:
first = [{id:1},{id:2},{id:3},{id:4},{id:5}]
second = [{id:3},{id:4},{id:5},{id:6},{id:7}]
first = first.filter (first_element) ->
second = second.filter (second_element) ->
first_element.remove = second_element.remove = yes if first_element.id is second_element.id
!second_element.remove?
!first_element.remove?
console.log(first.concat second) # [{id:1},{id:2},{id:6},{id:7}]
The explicit returns were removed, the if was put at the end of the line. yes is replaced with true and == is replaced with is.
While not shorter in lines, this one preserves the objects in the Arrays:
first = first.filter (firstElement) ->
keepFirst = yes
second = second.filter (secondElement) ->
keepFirst = (keepSecond = secondElement.id isnt firstElement.id) and keepFirst
keepSecond
keepFirst
Note that you can't use the and= operator, because it short cirquits.
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 a question regarding this type of code:
First = ["A","B","C"];
Second = ["D","E","F"];
Group = ["First", "Second"];
for gr = Group
current = gr;
for number = 1:numel(current)
my_variable(number) = current(number);
end
end
That's the reproduction of my problem. In this case my_variable is equal to "First" for example. But I wanted it to be "A" then "B" then "C" from variable named "First".
For my understanding this code should do the following:
1st step: for gr = Group means gr = First to Second
2nd step: current = gr; means current = First
3rd step: for number = 1:numel(current) means number = 1:3 (number of elements in "First")
4th step: my_variable(number) = current(number); means my_variable = First(1) = "A"
Instead of that I get my variable equal to "First" or "Second".
I hope you understand what I mean.
P.S. the string arrays I'm using with double quotes (" ") like First = ["A","B","C"]; are only available in Matlab 2016b or later.
You should use cell arrays to do this:
first = {'A','B','C'};
second = {'D','E','F'};
group = {first, second};
for group_ind = 1:numel(group)
current = group{group_ind};
my_variable = cell(1,numel(current));
for number = 1:numel(current)
my_variable{number} = current{number};
disp(my_variable)
end
end
For first and second, you can also use the string arrays:
first = ["A","B","C"];
second = ["D","E","F"];
group = {first, second};
for group_ind = 1:numel(group)
current = group{group_ind};
my_variable = strings(1,numel(current));
for number = 1:numel(current)
my_variable(number) = current(number);
disp(my_variable)
end
end
I have two versions of code - I wrote the second (more explicit) loop when the first didn't do what I wanted.
Where did I go wrong? I suspect a slicing problem (as in, I'm not correctly slicing the data out)
The first version, which doesn't do what I want, is commented out above the loop:
rBool = false(h.numDirs, h.numTimes, h.numR);
for d = 1:h.numDirs
U_first = h.data(d,1,:);
U_first = U_first{1};
for t = 2:h.numTimes
U = h.data(d,t,:);
U = U{1};
dU = abs(U-U_first);
%rBool(d,t,:) = (dU > (smallVal*U_first) | rBool(d,t-1));
for r=1:h.numR
rBool(d,t,r) = (dU(r) > (smallVal*U_first(r))| rBool(d,t-1,r));
end
end
end
You are missing the third index of the second rBool in your commented line:
rBool(d,t,:) = (dU > (smallVal*U_first) | rBool(d,t-1,:));
Although I'd parenthesize it like this:
rBool(d,t,:) = (dU > (smallVal*U_first)) | rBool(d,t-1,:);
The version you originally had implicitly assumed r==1, I think.
And you can simplify your code by setting
U = h.data{d,t,1};
instead of cutting out a cell vector and choosing the first element.
Let's say that I have 2 3D-Matrix:
A = rand(10,4,100);
B = rand(10,4,100);
L = gt(A,B);
Now I want substitute all elements of B with elements of A only where L==1but this doesn't work:
B(L==1,:,:) = A(L==1,:,:);
Any suggestion?
Our even shorter whithout find
B(L) = A(L);
Sounds like a job for the find() function.
p = find(L);
B(p) = A(p);
EDIT: Just realized you don't need the find() function. Just use logical indexing like this:
B(L==1) = A(L==1);
I am aware many of you will think this should be easily solvable. However, I have no clue about MATLAB.
Here goes my problem: when trying to execute the following example in the Command Window through the command
getLogReturnExcel('ALL.xls', {'ALL'}, 37000, 38000)
the cell-type error appears for this function. From what I understand however, when using {} the function should be grabbing the type inside {} (String in this case?) instead of the cell itself, which would be being grabbed if we were to use (), so there should be no error? Or is there something much more elementary that I might be overseeing? Thanks in advance for every bit of help; as you can tell I very much need it.
Cheers,
Ben
Here goes the function getLogReturnExcel:
function [logreturn, datearray] = getLogReturnExcel( datafilename, ticker, begindate, enddate )
[aanumber, aatext] = xlsread(datafilename);
aaticker = aatext(:,1);
aadate = aanumber(:,2);
aaret = zeros(length(aaticker),1);
aaret(1,1) = 0;
for i = 2:length(aaret)
aaret(i,1) = ln(aanumber(i,3))-ln(aanumber(i-1,3));
end
aadate = aadate(strcmp(aaticker,ticker));
aaret = aaret(strcmp(aaticker,ticker));
logreturn = aaret(aadate>=begindate & aadate<=enddate);
datearray = aadate(aadate>=begindate & aadate<=enddate);
return
The file 'ALL.xls' contains 3 columns, one with strings (the acronym for stocks) and two with numbers (I'm assuming double), one for the date in Excel-format and one with each day's stock standing.
The string can be obtained by using:
ticker{:}
or else the comparison in the lines
aadate = aadate(strcmp(aaticker,ticker));
aaret = aaret(strcmp(aaticker,ticker));
will be between strings and cell array.
Here is some documentation to access elements of a cell array.