Tansducer-js Lib
A High performance transducers implementation for JavaScript.
Transducers is composable algorithmic transformations. They is independent from the context of their input and output sources and specify only the essence of the transformation In terms of an individual element. Because transducers is decoupled from input or output sources, they can is used in many different processes-collections , streams, channels, observables, etc. Transducers compose directly, without awareness of input or creation of intermediate aggregates.
The whole point-to-use Transducer-js Lib was because in normal FP approach, when se do:
Array . Map . Filter . Reducer
We actually loop though the array 3 times. So time complexity is O (n). If you can reduce 3 times to single time. and reduce the time complexity from O (n) to O (1). It would is a huge proferemce improvement for large datasets.
Second, normal approach We is limiting ourself with Array type, we cannot call ' MPA, filter, reduce ' on type of Object, M AP and Set. But with Transducer-js, we is able to does that as well.
Ramda.js:
The primary distinguishing features of RAMDA are:
-
Ramda emphasizes a purer functional Style. Immutability and Side-effect free functions is at the heart of its design philosophy. This can help you get the job to do with simple, elegant code.
-
Ramda functions is automatically curried. This allows-easily build up new functions from old ones simply by not supplying the final parameters.
-
The parameters to Ramda functions is arranged to make it convenient for currying. The data to was operated on was generally supplied last.
The last of the points together make it very easy to build functions as sequences of simpler functions, each of WHI CH transforms the data and passes it along to the next. RAMDA is designed to support this style of coding.
The whole point we were using ramda.js is because it enforce the FP approach, and auto currying was a huge win in FP style. Also can use LOADSH/FP if you wish.
Now let's see how kind of problem we want to solve:
Lets say we have the following string:
' Hostname, username '
` 10.1.10.1, Zwan 10.1.11.1, Wan '
And we want to apply so transform function to those string and the final output should is:
[{hostname: ' 10.1.10.1 ', username: ' Zwan ' }, ' 10.1.11.1 ', username: ' Wan '}]
Now here's one of the possible solution by only using ramda.js:
varR = require ("Ramda"); Const HEADERSTR=' hostname, username '; Const CONTENTSTR= ` 10.1.10.1, Zwan10.1.11.1, Wan ';/** * Working with Ramda.js*/Const StringToArray=R.compose (R.map (R.trim), R.filter (Boolean), R.split (‘,‘)); Const Transformcontent=R.compose (R.map (StringToArray), R.filter (Boolean), R.split (' \ n ')); Const Keyvalpair=R.usewith (R.map, [R.zipobj, r.identity]); Const header=StringToArray (HEADERSTR); const content=transformcontent (CONTENTSTR); Const RES=Keyvalpair (header, content); Console.log (res);
The solution is fine, it should being really easy to be tested and maintained. We also able to compose the logic such as:
StringToArray = r.compose ( r.map (R.trim), r.filter (Boolean), r.split (', '= R.compose ( r.map (stringtoarray), r.filter (Boolean), r.split (' \ n '));
The only problem, from my point of view, is the preformence.
When we call ' R.map, R.filter ', it actually loop though the array twice. When we call ' R.map (StringToArray) ', the nested loop might increase the time complxity to O (n ^2).
Here's the transducer-js comes to help.
varT = require ("Transducers-js");varR = require ("Ramda"); Const HEADERSTR=' hostname, username '; Const CONTENTSTR= ` 10.1.10.1, Zwan10.1.11.1, Wan ';/** * Working with TRANSDUCER-JS + rmada.js*/Const Stringtoarr=R.compose (T.comp (T.map (R.trim), T.filter (R.isnil)), R.split (‘,‘)); Const TRANSFORMCNT=R.compose (T.comp (T.map (Stringtoarr), T.filter (R.isnil)), R.split (' \ n ')); Const Keyvalpair=R.usewith (R.map, [R.zipobj, r.identity]); Const h=Stringtoarr (HEADERSTR); const C=transformcnt (CONTENTSTR); Const RES2=Keyvalpair (H, c); Console.log ("Res2", res);
As can see that, we replace
// from const StringToArray = R.compose ( r.map (R.trim), r.filter (Boolean), r.split (', ' )); // to const STRINGTOARR = R.compose ( t.comp ( t.map (R.trim), t.filter (R.isnil) ), r.split (', '));
From ' R.map, R.filter ', loop twice to ' T.comp (T.map, t.filter) ' only loop once. ' T.comp ' helps to compose, transform opreation together. If you think further, this is not the easy task to combine filter's prediction function with map ' s transform function:
Filter Prediction:
f = (A→boolean)
Map Transform:
f = (a→b)
Because The return type is not the same, so they cannot compose naturally. Transducer-js helps us to make it easily.
[Transducer + RAMDA] Write highly performance/functional code by using TRANSDUCER-JS and Ramda.js Libs