1.用字符串代表数字来进行算术操作
描述:
// 比如
seven( times( five() ) ); // 相当于 7 * 5 = 35
four( plus( nine() ) ); // 4 + 9 = 13
eight( minus( three() ) ); // 8 - 3 = 5
six( dividedBy( two() ) ); // 6 / 3 = 2
看到这个第一眼就有点蒙逼,这肯定要使用高阶函数来完成,但如何实现,内心比较矛盾,最后看了一下别人的算法:
算法1:
["zero", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine"].forEach(function (name, n) {
this[name] = function(f) {return f ? f(n) : n}
});
var plus = n =>
a =>
a + n;
var minus = n =>
a =>
a - n;
var times = n =>
a =>
a * n;
var minus = n =>
a =>
a / n;
解析:
首先forEach函数利用0-9对应的索引返回一个函数,
如果这个函数参数存在则调用f(n), 如果不存在则直接
等于索引值,即0对应的是0,9对应的是9;
然后就是加减乘除各自也是一个高阶函数。
算法2:与上面类似
const numbers = 'zero one two three four five six seven eight nine'.split(' ')
const number = num => {
return operator => {
if (operator) return operator(num)
return num
}
}
const operator = op => {
return x => {
return y => {
return op(y, x)
}
}
}
// Numbers
numbers.forEach((name, index) =>
GLOBAL[name] = number(index)
)
// Operators
const plus = operator((x, y) => x + y)
const minus = operator((x, y) => x - y)
const times = operator((x, y) => x * y)
const dividedBy = operator((x, y) => x / y)
2.算出一个字符串中重复的字符个数(忽略大小写)
描述:
"abcde" -> 0 # no characters repeats more than once
"aabbcde" -> 2 # 'a' and 'b'
"aabbcdeB" -> 2 # 'a' and 'b'
"indivisibility" -> 1 # 'i'
"Indivisibilities" -> 2 # 'i' and 's'
我的算法:
function duplicateCount(text) {
var result = [];
var finalResult = [];
// 将text中重复的字符添加到result中
text.toLowerCase().split("")
.filter((v, idx, arr) =>
if (arr.indexOf(v) !== arr.lastIndexOf(v)) {
result.push(v);
}
)
// 将result中重复的字符去掉
finalResult = result.filter((v, idx, arr) =>
arr.indexOf(v) === idx
);
return finalResult.length;
}
我的算法虽然可行,但是比较啰嗦。别人的算法,利用正则:
function duplicateCount(text) {
return (
text
.toLowerCase().split("").sort().join("")
.match(/([^])\1+/g || []).length;
)
}
// 先讲字符串全变为小写然后变为数组,并且排序
// 然后再将字符按照从小到大组合成字符串
// 正则
// ([^]): 表示任意字符
// (..)\1: 表示前面()的组
// (..)\1+: 表示连着出现2次以及2次以上的
3.将字符串交替的变换大小写
描述:
toWeirdCase( "String" );//=> returns "StRiNg"
toWeirdCase( "Weird string case" );
//=> returns "WeIrD StRiNg CaSe"
做了半天没做出来,当需要多层嵌套时对数组操作时, 最好不要用箭头函数
别人的:
function toWeirdCase(string) {
return string.split(/\s+/).map(function(word) {
return word.split("").map(function(letter, i) {
return (i % 2 === 0) ? letter.toUpperCase() : letter.toLowerCase()
// 或者
// return letter[(!(i%2))?"toUpperCase":"toLowerCase"]()
// 这种表示方法利用对象的特性
}).join("");
}).join(" ");
}
本质上是高阶函数的运用, 需要注意的是, 当我们使用map之后,如果需要对内部item,再进行一次map, 这个时候需要返回一个函数, 在返回的函数中对map进行操作。
解析:
string.split(/\s+/)
//1. 将字符串出去空格变为数组
// "hello world this" => ["hello", "world", "this"]
string.split(/s+/).map(function(word) {
// ...
})
// 2.对每个单词进行操作
// 3.这时候需要对每个单词再一次进行map操作
return word.split(""){}
// 拆成数组
// ["h", "e", "l", "l", "o"]
// 内部逻辑处理之后合并成一个单词返回
// ["HeLlO", "WoRlD", "ThIs"]