rxjs - How to properly forkjoin an array of observables? - rxjs

The minimal TypeScript snippet below generates the following warning: #deprecated — Use the version that takes an array of Observables instead. I have looked at 1 and 2 but I wasn't able to achieve my objective. How to properly forkJoin the observables?
const v0: Observable<number[]> = of([0, 1, 2]);
const v1: Observable<number[]> = of([3, 4, 5]);
const v2: Observable<number[]> = of([6, 7, 8]);
const data: Observable<number[]>[] = [v0, v1, v2];
forkJoin(data);//#deprecated — Use the version that takes an array of Observables instead

You can simply use forkJoin([v0, v1, v2]). The forkJoin(a, b, c) it's deprecated anyway.

Related

How to return the value of a swap function

I want to ask if i can return more than one value using function.
when i make a function that is not necessarly returning one value like the swap functin,I'm not sure how to deal with it.Because in the end i want to return the two variables, let us consider them x and y
To explain more i tried to do this little function:
Function Swap(x:integer,y:integer)
Variables
temp:integer
Begin
temp=x
x=y
y=temp
return x,y
the thing that I'm not sure about is if i have the right to** return more than one value**?
You could just try it:
def some_func():
return 4, "five", [6]
a, b, c = some_func()
print(f"{a}, {b}, {c}")
>>> 4, five, [6]
Yes, you can return as many values from a func as you like. Python will pack all the return values into a single var, a tuple, and allows you to unpack them into multiple vars when the function returns. So, you could also do:
d = some_func()
print(type(d))
>>> <class 'tuple'>
print(d)
>>> (4, 'five', [6])

How to check for an undef value in a Matrix (in Julia) and assign a new value?

I want to create a matrix A of undefined values and have the following code that works just fine.
A = Matrix{Tuple{Float64, Array{Int64, 1}}}(undef, 100, 100)
Later, I want to check if a particular cell is undefined and if so, assign a value after computing it. I tried isdefined(A, i, j) but that gave an error for too many arguments. How can I check for #undef and assign only if it is undefined?
The documentation on isdefined provides a method only for a single dimensional array, how do I achieve the same on a matrix?
Use isassigned:
julia> A[2,3]=(3.0, [])
(3.0, Any[])
julia> isassigned(A,2,3)
true
julia> isassigned(A,3,3)
false
You can use the isassigned function (which is mentioned in the help string of isdefined, btw). Like isdefined it appears to only accept linear indices, but you can get those from LinearIndices.
julia> A = Matrix{Tuple{Float64, Array{Int64, 1}}}(undef, 100, 100);
julia> A[5, 4] = (2.1, [5])
(2.1, [5])
julia> isassigned(A, LinearIndices(A)[1, 1])
false
julia> isassigned(A, LinearIndices(A)[5, 4])
true
Edit: As demonstrated in the answer from #PrzemyslawSzufel, you don't need linear indices. Seems to be be undocumented, though, up to and including v1.5.1

Using ndarray_parallel Zip to iterate through rows of a Array2 and items of Array1

I would like to iterate through rows of an Array2 and items of an Array1 in parallel and do some computation on them with side effects.
I tried something like below,
extern crate ndarray;
extern crate ndarray_parallel;
use ndarray::{Array2, Array, Zip, Axis};
use ndarray_parallel::prelude::*;
fn main() {
let mut a = Array2::<f64>::zeros((5, 5));
let b = Array::from_iter(0..5);
let c = vec![1,2,3,4,5];
let mut d = vec![1,2,3,4,5];
let z = Zip::from(a.axis_iter(Axis(0))).and(&b);
z.par_apply(|x,y| {d[*y as usize] = 10});
}
But the compiler is complaining.
Can anyone advise?
Multiple misconceptions in your code, correct me if any of the followings is not what you want:
b seems to serve as index to the vector. You can use Zip::indexed to produce index along with element directly, no need for an explicit index array.
axis_iter returns an iterator which traverses all axis of underlying ndarray. You probably want index_axis to traverse one of them.
Your arrays host both integers and floats. In rust you can't apply arithmetic operations between the two.
par_apply takes a Fn, so it can't mutate captured variables.
All things considered, the code probably should look like this:
use ndarray::{Array2, Zip, Axis};
use ndarray_parallel::prelude::*;
fn main() {
let a = Array2::<f64>::zeros((5, 5));
let mut d = vec![1.,2.,3.,4.,5.];
Zip::indexed(a.index_axis(Axis(0), 0))
.and(&mut d)
.par_apply(|_i, x, y| *y = x + 10.);
}

How do I memoize the last result in a chain of observables?

I've modelled a navigation concept reactively, (a user navigating forward and backward pages) but I'm having trouble optimizing it using Reactive Extensions. I'm sure it's some kind of buffering or sharing operator, but I'm not quite sure which one it is or where to shove it.
This is a working, simplified example of what I've implemented, in TypeScript and with rxjs.
Each time the user clicks, we increment it by one step. (In reality, there is a network request in here which might return a new step or none, hence why this is not a simple + 1.)
describe('navigate', () => {
it('should increment', () => {
const initial = Observable.of(0);
const plusOne = (ns: Observable<number>) => ns.pipe(map(n => n + 1), tap(x => console.log("Computed", x)));
const clicks = Observable.from([plusOne, plusOne, plusOne]);
const expected = cold("(wxyz|)", { w: 0, x: 1, y: 2, z: 3 });
const result = clicks.pipe(
scan(
(s: Observable<number>, x: (ns: Observable<number>) => Observable<number>) => x(s),
initial),
startWith(initial),
switchAll(),
)
expect(result).toBeObservable(expected);
})
})
It produces the correct output, and the test passes.
But in terms of execution, in the console you'll see this printed:
Computed 1
Computed 1
Computed 2
Computed 1
Computed 2
Computed 3
which makes sense, but if the plusOne operation is expensive (e.g. a network request) it won't do to have the plusOnes computed from the start every time.
How do I memoize the result of the last plusOne so that subsequent plusOnes need not calculate the entire chain again?
Or if I'm looking at this the wrong way, how should I be approaching this problem?
Attempt
Since the top of this question, I did think of one solution.
const result = clicks.pipe(
scan(
(s: Observable<number>, x: (ns: Observable<number>) => Observable<number>) => x(s).pipe(shareReplay(1)),
initial),
startWith(initial),
switchAll(),
)
which executes like:
Computed 1
Computed 2
Computed 3
However I think this leads to a chain which would look like:
xs.map(x => x + 1).shareReplay(1).map(x => x + 1).shareReplay(1).map(x => x + 1).shareReplay(1)
and which I don't think would be terribly efficient (if each shareReplay(1) caches a value). Is there a better way to do this?

Merge values of objects with ImmutableJS

I have a List of several objects. All with the same keys. I'm trying to find an efficient way to reduce the values into a single object.
var list = Immutable.fromJS([{
first: 3,
second: 4,
third: 2
}, {
first: 7,
second, 6,
third: 8
}]);
Wanting to return:
{first: 10,
second: 10,
third: 10}
I'm really just trying to find a way to merge an object, but add the values instead of replacing them. Hope that makes sense.
take the outer array as List and while running reduce, merge inner Maps
list.reduce(function(a, b){
return a.
mergeWith(function(x, y){
return x + y;
}, b)
}).toJS()

Resources