oh-to-be-pure-again
In the impure portion,checkAge
depends on the mutable variableminimum
to determine the result. In other words, it depends on system state which is disappointing because it increases the cognitive load by introducing an external environment.
// Impure
let minimum = 21;
let checkAge = function(age) {
return age >= minimum;
};
// Pure
let checkAge = function(age) {
let minimum = 21;
return age >= minimum;
};
function squareAll(items) {
return items.map(square);
}
//Pure functions
function square(x) {
return x * x;
}
//Impure functions
function squareAll(items) {
for (let i = 0; i < items.length; i++) {
item[i] = square(items[i]);//It modified the incoming data;
}
}
slice & splice
mostly-adequate-guide
In functional programming, we dislike unwieldy functions likesplice
that mutate data.
let xs = [1, 2, 3, 4, 5];
// Impure
xs.splice(0, 3);
//=> [1,2,3]
xs.splice(0, 3);
//=> [4,5]
xs.splice(0, 3);
//=> []
// Pure
xs.slice(0, 3);
//=> [1,2,3]
xs.slice(0, 3);
//=> [1,2,3]
xs.slice(0, 3);
//=> [1,2,3]
//Mutable
function addOne(numArray: any[]): any[] {
for (let x in numArray) {
numArray[x] = numArray[x] + 1;
}
return numArray;
}
function addOne(numArray: any[]): any[] {
let addedArray: any[];
for (let x in numArray) {
addedArray[x] = numArray[x] + 1;
}
return addedArray;
}
function addOne(numArray: any[]): any[] {
let addedArray: any[] = new Array();
for (let x of numArray) {
addedArray.push(x + 1);
}
return addedArray;
}
function addOne(numArray: any[]): any[] {
let addedArray: any[];
numArray.forEach((element, index) => {
addedArray[index] = element + 1;
});
return addedArray;
}
//Immutable
function addOne(numArray: any[]): any[] {
return numArray.map((item) => {
return item + 1;
})
}
let a = [1, 2, 3, 4, 5];
Object.freeze(a);
console.log(addOne(a));
for…in
for…of
foreach
map
//for loop
function accumulate(n) {
let result = 0;
for (n; n > 0; n--) {
result = n + result;
}
return result;
}
//Recursive loop
function accumulate(n) {
if (n === 0) {
return 0;
} else {
return n + accumulate(n - 1);
}
}
//Recursive loop
function accumulate(n) {
if (n === 0) {
return 0;
} else {
return n + accumulate(n - 1);
}
}
//Tail Call Optimization
"use strict";
function accumulate(n, result) {
if (n === 0) {
return result;
} else {
return accumulate(n - 1, n + result);
}
}
尾调用优化
http://web.jobbole.com/86086/
const hi = function (name) {
return "Hi " + name;
};
const greeting = function (name) {
return hi(name);
};
hi;
// function(name){
// return "Hi " + name
// }
hi("jonas");
// "Hi jonas"
const greeting = hi;
greeting("jonas");
// "Hi jonas"
const ajaxCall = function (callback) {
const json = {
a: "123"
}//do something
return callback(json);
}
const getServerStuff = function (callback) {
return ajaxCall(function (json) {
return callback(json);
});
};
const getServerStuff = ajaxCall;
return ajaxCall(function(json){
return callback(json);
});
return ajaxCall(callback);
const getServerStuff = function(callback){
return ajaxCall(callback);
};
const getServerStuff = ajaxCall;
函数式编程入门教程——阮一峰
compose(f, compose(g, h))
compose(compose(f, g), h)
compose(f, g, h)
找到用户 Scott 的所有未完成任务,并按到期日期升序排列
const data = {
result: "SUCCESS",
interfaceVersion: "1.0.3",
requested: "10/17/2013 15:31:20",
lastUpdated: "10/16/2013 10:52:39",
tasks: [
{
id: 104, complete: false, priority: "high",
dueDate: "2013-11-29", username: "Scott",
title: "Do something", created: "9/22/2013"
},
{
id: 105, complete: false, priority: "medium",
dueDate: "2013-11-22", username: "Lena",
title: "Do something else", created: "9/22/2013"
},
{
id: 107, complete: true, priority: "high",
dueDate: "2013-11-22", username: "Mike",
title: "Fix the foo", created: "9/22/2013"
},
{
id: 108, complete: false, priority: "low",
dueDate: "2013-11-15", username: "Punam",
title: "Adjust the bar", created: "9/25/2013"
},
{
id: 110, complete: false, priority: "medium",
dueDate: "2013-11-15", username: "Scott",
title: "Rename everything", created: "10/2/2013"
},
{
id: 112, complete: true, priority: "high",
dueDate: "2013-11-27", username: "Lena",
title: "Alter all quuxes", created: "10/5/2013"
}
]
};
const fetchData = function () {
return Promise.resolve(data);
};
let getIncompleteTaskSummaries = function (membername) {
return fetchData()
.then(function (data) {
return data.tasks;
})
.then(function (tasks) {
let results = [];
for (let i = 0, len = tasks.length; i < len; i++) {
if (tasks[i].username == membername) {
results.push(tasks[i]);
}
}
return results;
})
.then(function (tasks) {
tasks.sort(function (first, second) {
let a = first.dueDate, b = second.dueDate;
return a < b ? -1 : a > b ? 1 : 0;
});
return tasks;
});
};
getIncompleteTaskSummaries("Scott").then((tasks) => {
console.log(tasks)
})
let R = require('ramda');
let data = {
result: "SUCCESS",
interfaceVersion: "1.0.3",
requested: "10/17/2013 15:31:20",
lastUpdated: "10/16/2013 10:52:39",
tasks: [
{
id: 104, complete: false, priority: "high",
dueDate: "2013-11-29", username: "Scott",
title: "Do something", created: "9/22/2013"
},
{
id: 105, complete: false, priority: "medium",
dueDate: "2013-11-22", username: "Lena",
title: "Do something else", created: "9/22/2013"
},
{
id: 107, complete: true, priority: "high",
dueDate: "2013-11-22", username: "Mike",
title: "Fix the foo", created: "9/22/2013"
},
{
id: 108, complete: false, priority: "low",
dueDate: "2013-11-15", username: "Punam",
title: "Adjust the bar", created: "9/25/2013"
},
{
id: 110, complete: false, priority: "medium",
dueDate: "2013-11-15", username: "Scott",
title: "Rename everything", created: "10/2/2013"
},
{
id: 112, complete: true, priority: "high",
dueDate: "2013-11-27", username: "Lena",
title: "Alter all quuxes", created: "10/5/2013"
}
]
};
let fetchData = function () {
return Promise.resolve(data);
};
let getIncompleteTaskSummaries = function (membername) {
return fetchData()
.then(R.prop('tasks'))
.then(R.filter(R.propEq('username', membername)))
.then(R.reject(R.propEq('complete', true)))
.then(R.sortBy(R.prop('dueDate')));
};
getIncompleteTaskSummaries('Scott').then(r => console.log(r));
下面有一段字符串,请问其中最长的单词有多少个字符?
const R = require('ramda');
const str = 'Lorem ipsum dolor sit amet consectetur adipiscing elit';
// 以空格分割单词
const splitBySpace = s => s.split(' ');
// 每个单词的长度
const getLength = w => w.length;
// 词的数组转换成长度的数组
const getLengthArr = arr => R.map(getLength, arr);
// 返回较大的数字
const getBiggerNumber = (a, b) => a > b ? a : b;
// 返回最大的一个数字
const findBiggestNumber =
arr => R.reduce(getBiggerNumber, 0, arr);
const getLongestWordLength = R.pipe(
splitBySpace,
getLengthArr,
findBiggestNumber
);
// 上面代码的另一种写法
const getLongestWordLength = R.pipe(
R.split(' '),
R.map(R.length),
R.reduce(R.max, 0)
);
console.log(getLongestWordLength(str)) // 11