目录
- 说在前面
- 开始
- Sum All Numbers in a Range
- Diff Two Arrays
- Roman Numeral Converter
- Where art thou
- Search and Replace
- Pig Latin
- DNA Pairing
- Missing letters
- Boo who
- Sorted Union
- Convert HTML Entities
- Spinal Tap Case
- Sum All Odd Fibonacci Numbers
- Sum All Primes
- Smallest Common Multiple
- Finders Keepers
- Drop it
- Steamroller
- Binary Agents
- Everything Be True
- Arguments Optional
- 结语
说在前面
这是要一篇非常简单的新手能看懂的文章,希望你喜欢。由于在 freecodecamp 中貌似!?无法使用 ES6
的某些语法,未测试具体。所以基本上用古老?!的ES5,4
写成,谢谢。在写本博文前没有参考过别人的做法,纯手打,我的方法肯定不是最好,只是以我自己喜欢的方式在写而已。
纯原创,转载请联系作者https//:wusuai1995@qq.com
、givingwu@gmail.com
。
- freecodecamp China
- 不明白
API
请参考MDN给出的解释 - 个别题目没有判断函数参数及其类型,仅通过了
Run tests
- 如果你最近在写微信小程序的蓝牙的话请参考wx-bluetooth
- 有疑惑请留言
开始
Sum All Numbers in a Range
- 先对传入数组升序排列,拿到 [min, max]
- 然后 generateArr 成一个 [min, min+1, min+2, ..., max]
- Array.prototype.reduce 方法从左至右求和
function sumAll(arr) {
if (!Array.isArray(arr) || !arr || !arr.length) return;
arr = arr.sort(function(a, b){ return a-b;});
arr = generateArr(arr[0], arr[1]);
console.log(arr);
return arr.reduce(function(accu, curr){
return accu += curr;
});
}
function generateArr(min, max) {
var arr = [];
while (min <= max) {
arr.push(min);
min++;
}
return arr;
}
Diff Two Arrays
- 合并两个数组成一个数组
- 通过一个 obj 缓存数组中每项的出现次数
- 返回 obj[arr[i]] 仅出现一次的项组成的数组
function diff(arr1, arr2) {
if (!Array.isArray(arr1) || !Array.isArray(arr2)) return;
var newArr = arr1.concat(arr2);
return unique(newArr);
}
function unique(arr) {
var a = [], i, l, item, key, obj = {};
for (i = 0, l = arr.length; i < l; i++) {
item = arr[i];
if (obj[item] === undefined) {
obj[item] = [item];
} else {
obj[item].push(item);
}
}
console.log(arr, obj);
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key].length === 1){
a = a.concat(obj[key]);
}
}
}
return a;
}
Roman Numeral Converter
- 先把每个数所对应的阿拉伯数字和罗马数字取出来并一一对应
var RomanNumArr = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],
RomanNumStrArr = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
- 然后对给出的数进行 倒推求余 的推算并返回对应数字数组,比如139 = [100 + 39] = [100 + 3 * 10 + 9] = [100, 10, 10, 10, 9]
function getSeparatedRomanNumArr (num, arr) {
arr = arr || [];
for (var i = 0, l = RomanNumArr.length; i < l; i++) {
var curr = RomanNumArr[i], next, int;
if (num >= curr) {
if (num % curr === 0) {
return pushNumByTimes2Arr(curr, num / curr, arr);
} else {
next = num % curr;
int = num - next;
return getSeparatedRomanNumArr(next, pushNumByTimes2Arr(curr, int / curr, arr));
}
}
}
}
function pushNumByTimes2Arr(num, times, arr) {
while (times) {
arr.push(num);
times--;
}
return arr;
}
- 将每个阿拉伯数字对上罗马数字,然后对返回的数组进行 Array.prototype.join 即可,例如上面例子139 = [100, 10, 10, 10, 9] = ['C', 'X', 'X', 'X', 'IX'].join('') = 'CXXXIX'
function convert(num) {
if (!num || 'number' !== typeof +num) throw new TypeError();
var romanNumArr = getSeparatedRomanNumArr(num);
return romanNumArr.map(function(item){
return RomanNumStrArr[RomanNumArr.indexOf(item)];
}).join('');
}
Where art thou
for
loop取出collection
中的每个对象的keys
然后与source
对象的keys
进行比对通过函数getSameItems
- 将当前
collection[i]
的key
的与sameKeys
进行比对,如果全部全等就match
反正false
function where(collection, source) {
var arr = [], sourceKeys = Object.keys(source), obj, key, objKeys,
sameKeys, i, l = collection.length, j, k, matched;
for (i = 0; i < l; i++) {
obj = collection[i];
objKeys = Object.keys(obj);
if (objKeys.length < sourceKeys.length) continue;
sameKeys = getSameItems(sourceKeys, objKeys);
if (sameKeys.length < sourceKeys.length) continue;
matched = true;
if (sameKeys && sameKeys.length) {
for (j = 0, k = sameKeys.length; j < k; j++) {
key = sameKeys[j];
if (obj[key] !== source[key]) {
matched = false;
}
}
}
if (matched) arr.push(obj);
}
return arr;
}
function getSameItems (arr1, arr2) {
if (!arr1 || !arr1.length || !arr2 || !arr2.length) throw new TypeError();
var arr = [];
arr1.forEach(function(item){
if (~arr2.indexOf(item)) {
arr.push(item);
}
});
return arr;
}
Search and Replace
function myReplace(str, before, after) {
after = isUpperCase(before[0]) ? camelize(after) : after;
str = str.replace(before, after);
return str;
}
function camelize (str) {
return str.slice(0, 1).toUpperCase() + str.slice(1, str.length);
}
function isUpperCase(s) {
return s === s.toUpperCase();
}
Pig Latin
- 根据题意先写出元音数组
vowels
,然后分割字符串成数组并比对是否存在元音字符,如果有则立即返回该index
位置,反之返回undefined
- 如果
index === 0
则返回str + 'way'
反之返回str.slice(vowelIndex, str.length) + str.substr(0, vowelIndex) + 'ay'
;
function translate(str) {
var vowelIndex = findVowelsIndex(str);
str = vowelIndex === 0 ? str + 'way' : str.slice(vowelIndex, str.length) + str.substr(0, vowelIndex) + 'ay';
return str;
}
function findVowelsIndex (str) {
var vowels = ['a', 'e', 'i', 'o', 'u'];
var strArr = str.split(''), i, l, index;
for (i = 0, l = strArr.length; i < l; i++) {
index = vowels.indexOf(strArr[i]);
if (~index) {
return i;
}
}
}
DNA Pairing
function pair(str) {
var strArr = str.split(''), pairArr = [], pair, i, l;
for (i = 0, l = strArr.length; i < l; i++) {
switch(strArr[i]){
case 'C':
pair = 'G';
break;
case 'G':
pair = 'C';
break;
case 'A':
pair = 'T';
break;
case 'T':
pair = 'A';
break;
}
pairArr.push([strArr[i], pair]);
}
return pairArr;
}
Missing letters
- 比对给出的
str
的每个字符,并全部转换成 - 如果当前字符的 charCode 不等于
next
的charCode
则找到了该 迷失字符
function fearNotLetter(str) {
var strArr, i, l, curr, next, noMissing = true;
strArr = str.split('').map(function(word){
return word.charCodeAt();
});
for (i = 0, l = strArr.length; i < l; i++) {
curr = strArr[i];
next = strArr[i + 1];
console.log('curr:', curr, 'next:', next);
if (i !== l - 1 && ++curr !== next) {
str = String.fromCharCode(curr);
noMissing = false;
break;
}
}
return noMissing ? undefined : str;
}
Boo who
function boo(bool) {
// What is the new fad diet for ghost developers? The Boolean.
if (typeof bool !== 'boolean') return false;
return true;
}
Sorted Union
function unite(arr1, arr2, arr3) {
return Array.prototype.reduce.call(arguments, function(accu, curr){
console.log('accu:', accu);
console.log('curr:', curr);
curr = curr.filter(function(item){
return !~accu.indexOf(item);
});
return accu.concat(curr);
});
}
Convert HTML Entities
function convert(str) {
var i, j, reg, chars = ['&', '<', '>', '"', "'"], strs = ['&', '<', '>', '"', '''];
for (i = 0, l = chars.length; i < l; i++) {
reg = new RegExp('\' + chars[i], 'gm');
str = str.replace(reg, strs[i]);
}
return str;
}
Spinal Tap Case
function spinalCase(str) {
// "It's such a fine line between stupid, and clever."
// not, there is a comma still.
// --David St. Hubbins
var reg1 = /(s|\_)/g, reg2 = /([A-Z])/g;
if (reg1.test(str)) {
str = str.replace(reg1, '-');
} else if (reg2.test(str)) {
str = str.replace(reg2, '-$1');
}
str = str.toLowerCase();
return str;
}
Sum All Odd Fibonacci Numbers
- 先拿到斐波那契中所有小于 num 的数
- 然后求该数组中所有奇数(odd)项的和
function sumFibs(num) {
if (num <= 2) return num;
var a = 1, b = 1, arr = [a, b], sum = 0, i, l;
while (sum < num) {
sum = a + b;
if (sum <= num) arr.push(sum);
a = b;
b = sum;
}
console.log(arr);
num = 0;
for (i = 0, l = arr.length; i < l; i++) {
if (arr[i] % 2 !== 0) {
num += arr[i];
}
}
return num;
}
Sum All Primes
- 先将所有数组转出来(抱歉这里用了ES6的新方法
Array.from
,请参考MDN Array.from) - 判断每一个数是否是质数,通过函数isPrime
function sumPrimes(num) {
return Array.from({length: num}).map(function(item, index){
return ++index;
}).filter(function(item){
return isPrime(item);
}).reduce(function(accu, curr){
return accu += curr;
});
}
function isPrime (num) {
if (num <= 1) return;
var i, l, prime = true;
for (i = 2, l = num / 2 + 1; i < l; i++) {
if (num % i === 0) {
prime = false;
break;
}
}
return prime;
}
Smallest Common Multiple
PS: 这又是一个继罗马数字后不错的中级算法题
先上一波我用到的资料(即思路):
- 一个优秀的答案
- Git上老外的答案
- 如何求最小公倍数,我选用该帖子中 分解质因数法,所以我们得先求出所有的该区间中每个数的质因数数组,然后去重,最后乘上所有数的质因数
- 欧几里德算法
- 最大公约数
- 质因数分解
一个优秀的答案,同时向欧几里德表示respect
。
// *?!
Finders Keepers
function find(arr, func) {
var num = 0;
return arr.filter(func)[0];
}
Drop it
PS: 那一段卖队友也是很666,我表示赞同。但辅助会怎么想?
function drop(arr, func) {
// Drop them elements.
var n = arr.shift();
if (n !== undefined) {
if (!func(n)) {
return drop(arr, func);
} else {
arr.unshift(n);
return arr;
}
} else {
return [];
}
return arr;
}
Steamroller
function steamroller(arr) {
// I'm a steamroller, baby
var result = [], i, l;
for(i = 0, l = arr.length; i < l; i++){
if(Array.isArray(arr[i])){
result = result.concat(steamroller(arr[i]));
}else{
result.push(arr[i]);
}
}
return result;
}
Binary Agents
- 将二进制字符串参数通过
空格
切分为数组 - 将2进制转为10进制
- 通过
String.fromCharCode
返回字符串
function binaryAgent(str) {
return str.split(/s/g).map(function(s){
return String.fromCharCode(parseInt(s, 2));
}).join('');
}
Everything Be True
function every(collection, pre) {
// Is everyone being true?
return collection.every(function(item) {
return item[pre];
});
}
Arguments Optional
函数curry化参考JavaScript currying
function add(a, b) {
var args = Array.prototype.slice.call(arguments, 0);
if (typeof a !== 'number') return undefined;
if (args.length < 2) {
return function (b) {
if (typeof b !== 'number') return undefined;
args.push(b);
return add.apply(this, args);
};
} else {
if (typeof b !== 'number') return undefined;
}
return a + b;
}
结语
不算上我做题的时间,我就是复制自己写好的代码也花了一段时间。而且部分题目没有被 freeCodeCamp 记录了,又重新来一次,但只有前几道是。应该是间隔一段时间后,数据会被清掉而只记录是否完成状态。
表示这个 Smallest Common Multiple 我写的递归未过,所以不贴。
感谢上面贴出的所有引用连接,如果有任何引用存在问题,请联系作者立即下线。
观看容易,手打不易,且看且学习。