How can I perform operations in JavaScript just like we do pipeline of operations in Java streams?
Maybe later (or never) you can use the actual experimental pipeline operator |>
, which has the following syntax:
expression |> function
Your wanted result could be achieved by taking the functions as separate functions and iterate the stream array for each pipe.
This works only in FF. From version 58: this feature is behind the --enable-pipeline-operator
compile flag.
const
a = x => { x = x * x; console.log("map1=" + x); return x; },
b = x => { x = x * 3; console.log("map2=" + x); return x; },
c = x => console.log("forEach=" + x)
var nums = [1, 2, 3, 4, 5, 6];
nums.forEach(v => v |> a |> b |> c);
The same with a pipe as function (function composition enabling piping) with a closure over the wanted functions.
const
pipe = (...functions) => input => functions.reduce((acc, fn) => fn(acc), input),
a = x => { x = x * x; console.log("map1=" + x); return x; },
b = x => { x = x * 3; console.log("map2=" + x); return x; },
c = x => console.log("forEach=" + x)
var nums = [1, 2, 3, 4, 5, 6],
pipeline = pipe(a, b, c);
nums.forEach(pipeline);
If you put each function operation into an array, you can iterate over that array with reduce
and pass the last calculated value along in the accumulator until the end of the function array is reached:
var nums = [1,2,3,4,5,6 ];
var fns = [
(x) => {
x = x * x;
console.log('map1=' + x);
return x;
},
(x) => {
x *= 3;
console.log('map2=' + x);
return x;
},
(x) => {
console.log(x);
return x;
}
];
nums.forEach((num) => {
fns.reduce((lastResult, fn) => fn(lastResult), num);
// pass "num" as the initial value for "lastResult",
// before the first function has been called
});
You can't use nums.map
because .map
will necessarily iterate through the whole input array before resolving to the mapped output array (after which the mapped output array will then have another .map
called on it).
The equivalent to Java's streams are JavaScript's iterators. Iterator objects unfortunately don't have a map
method (yet), but you can easily write one yourself (and even install it on the prototype if you want method syntax).
function* map(iterable, f) {
for (var x of iterable)
yield f(x);
}
var nums = [1,2,3,4,5,6];
function square(x) {
x = (x * x);
console.log('map1='+x);
return x;
}
function triple(x) {
x = x * 3;
console.log('map2='+x);
return x;
}
for (const x of map(map(nums.values(), square), triple)) {
console.log('forEach='+x);
}
Also notice that in functional programming, order doesn't matter for pure operations - you shouldn't need to rely on the execution order if you are using map
.