This is the 8th day of my participation in the genwen Challenge
This series also does not have any tricks, is to complete the usual interview some handwriting functions, test these simple implementation of the advantage is that you can see the basic coding level, and take a short time, a more comprehensive view of your code strength. Generally, there are not many boundary conditions, so that the interview time is not enough, the investigation is not comprehensive.
If you don’t know or are not clear about the API, just ask the interviewer directly, how to use the API under Google anyone can immediately understand the knowledge also can’t see the level. The key is in the implementation process, and your coding status, habits, clarity of thought and so on.
Note that it is a simple implementation, not a complete implementation, it is important to clear the concept and clear implementation ideas, it is suggested to explain the concept first => write use cases => write pseudo-code => then realize specific functions, and then optimize, step by step.
18. Compose (function combination)
What is the
This is a concept in functional programming.
In a nutshell, this is a composition:
var compose = function(f, g) {
return function(x) {
return f(g(x));
};
};
Copy the code
F and g are functions, and x is the value “piped” between them.
Combinations look like feeding functions. You are the breeder. Choose two functions that have special features and that you like and combine them to produce a brand new function. Combinations can be used as follows:
// uppercase
let toUpperCase = function(x) {
return x.toUpperCase();
};
// The surprise function adds exclamation and tone
let exclaim = function(x) {
return x + ' ao ao ao!!! ';
};
// combine the two functions
let shout = compose(exclaim, toUpperCase);
console.log(shout("hello, my friend"))
// HELLO, MY FRIEND ao ao ao!!!
Copy the code
Note that the compose function is something you should implement yourself (or use the library function). This is just a use case, and we’ll write one by hand later so you can test it out.
In the definition of compose, g will execute before f, so a right-to-left data flow is created. This is much more readable than nesting a bunch of function calls, and if not combined, the shout function would look like this:
let shout = function(x) {
// Function nesting
return exclaim(toUpperCase(x));
};
// Let's make it a little more complicated
let complexFn = function(x) {
return gn(fn(fn1(exclaim(toUpperCase(x)))));
};
Copy the code
Notice that the code runs from right to left, not from inside out, and notice the order in which the functions are executed.
let toUpperCase = function(x) {
return x.toUpperCase();
};
// The surprise function adds exclamation and tone
let exclaim = function(x) {
return x + ' ao ao ao!!! ';
};
// This time we execute exclaim first, then execute uppercase, so the modal is also capitalized
let shoutRe = compose(toUpperCase, exclaim);
console.log(shoutRe("hello, my friend"))
HELLO, MY FRIEND AO AO AO!!!
Copy the code
Think about why right to left? Although we can define a left-to-right version, the right-to-left implementation is more mathematical — yes, the concept of composition comes straight from a math textbook. In fact, it’s time to look at one property that all combinations have — associativity.
const associative = compose(f, compose(g, h)) == compose(compose(f, g), h);
// true
Copy the code
This property is associative, and associative means that it doesn’t matter whether you put g and H in a group or f and G in a group. {(f, g), h} === {f, (g, h)}
let toUpperCase = (x) = > x.toUpperCase();
let exclaim = (x) = > x + ' ao ao ao!!! ';
// We add a function with a name at the beginning
let nameHead = (x) = > 'neverMore ' + x;
/ / combined rate
let associative1 = compose(toUpperCase, compose(exclaim, nameHead));
let associative2 = compose(compose(toUpperCase, exclaim), nameHead);
console.log(associative1('hello')) // NEVERMORE HELLO AO AO AO!!!
console.log(associative2('hello')) // NEVERMORE HELLO AO AO AO!!!
Copy the code
Because it doesn’t matter how the compose calls are grouped, the result is the same. This also gives us the ability to write a variadic composition.
In the previous example we had to write two combinations, but since combinations are associative, we can just write one and pass it as many functions as we want, and then let it decide how to group it.
let associative = compose(toUpperCase, exclaim, nameHead);
console.log(associative('hello')) // NEVERMORE HELLO AO AO AO!!!
// We can continue to add functions
letassociativeN = compose(toUpperCase, exclaim, nameHead, fn4, fn5, ...) ;Copy the code
Using associative laws gives us great flexibility and the peace of mind that there will be no surprises in the outcome of the execution.
One of the nice things about associativity is that any group of functions can be taken apart and packaged together in their own way. You can also use libraries like Lodash, underscore, and Ramda to find many basic functions (and combine them to make your own more powerful libraries)
There’s no right answer — we just build Legos the way we like them. In general, the best practice is to make the composition reusable. If you’re familiar with Fowler’s Refactoring, you probably recognize this process as “Extract Method” — just don’t worry about the state of the object.
Ok, so having said that, you should understand all aspects of the concept, and you should have a lot of use cases for how to implement it.
Simple handwriting implementation
First of all, reduce, API need to understand.
implementation
- Let’s write a test case
Test cases are already written in the above concept and are directly usable.
- Implement master logic
Focus on
- What we return is a brand new function
- Pay attention to
reduce
The traversal order isFrom left to right.compose
是From right to leftRun.
function compose(. fns) {
// The boundary conditions are omitted
return fns.reduce(
(acc, cur) = > {
return (. args) = >acc(cur(... args)) } ); }// Use the arrow function, but I do not like this way, one line is too long, not easy to read, and to make trouble, not enough semantic
// let compose = (... fns) => fns.reduce((acc, cur) => (... args) => acc(cur(... args)))
let toUpperCase = (x) = > x.toUpperCase();
let exclaim = (x) = > x + ' ao ao ao!!! ';
let nameHead = (x) = > 'neverMore ' + x;
let shout = compose(exclaim, toUpperCase);
console.log(shout("hello, my friend")) // HELLO, MY FRIEND ao ao ao!!!
let shoutRe = compose(toUpperCase, exclaim);
console.log(shoutRe("hello, my friend")) // HELLO, MY FRIEND AO AO AO!!!
/ / combined rate
let associative1 = compose(toUpperCase, compose(exclaim, nameHead));
console.log(associative1('hello')) // NEVERMORE HELLO AO AO AO!!!
let associative2 = compose(compose(toUpperCase, exclaim), nameHead);
console.log(associative2('hello')) // NEVERMORE HELLO AO AO AO!!!
let associative = compose(toUpperCase, exclaim, nameHead);
console.log(associative('hello')) // NEVERMORE HELLO AO AO AO!!!
Copy the code
This book is recommended if you want to learn more about functional programming
In addition, we recommend another series of articles, very simple, on the front of the advanced students are very effective, wall crack recommended!! Core concepts and algorithms disassembly series remember to like ha
If you want to brush the questions with me, you can add me on wechat. Click here to make a friend Or search my wechat account, infinity_9368. You can chat with me and add my secret code “Tianwang Gaidihu”. Verify the message please send me Presious tower shock the rever Monster, I see it through, after adding I will do my best to help you, but pay attention to the way of asking questions, it is suggested to read this article: the wisdom of asking questions
reference
- Llh911001. Gitbooks. IO/mostly – at…