找出多个数组中的最大数
如:largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]]) 应该返回 [27,5,39,1001].
function largestOfFour(arr) {
var array = [];
arr = arr.map(function(val, idx){
val.sort(function(a,b){ return b-a;});
array[idx] = val[0];
});
return array;
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
句中单词首字母大写 (Title Case a Sentence)
比如接收的是 "short sentence",那么输出就是 "Short Sentence",如果接收的是 "shOrT sEnTEnce",那么输出也应该是 "Short Sentence"
function titleCase(str) {
return str.toLowerCase().split(" ").map(function (word) {
return word[0].toUpperCase() + word.slice(1);
}).join(" ");
}
中级解法
function titleCase(str) {
return str.toLowerCase().replace(/(\s|^)[a-z]/g, function (match) {
return match.toUpperCase();
})
}
删除数组中的所有假值
在JavaScript中,假值有false、null、0、""、undefined 和 NaN。
function bouncer(arr) {
arr = arr.filter(function(val){
return val;
});
return arr;
}
bouncer([false, null, 0, NaN, undefined, ""]); // 返回 []
摧毁数组
实现一个摧毁(destroyer)函数,第一个参数是待摧毁的数组,其余的参数是待摧毁的值。
function destroyer(arr) {
var args = [];
for(var i = 1; i < arguments.length; i++){
args.push(arguments[i]);
}
var temp = arr.filter(function(item,index,array){
return args.indexOf(item) < 0; // indexOf()查询不到是返回-1;
});
return temp;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3); // 返回 [1,1]
Diff Two Arrays
比较两个数组,然后返回一个新数组,该数组的元素为两个给定数组中所有独有的数组元素。换言之,返回两个数组的差异。
function diff(arr1, arr2) {
return arr1.filter(function(v){
return arr2.indexOf(v)==-1; //第一个数组在第二个数组中不同的项
}).concat(arr2.filter(function(v){
return arr1.indexOf(v)==-1;
})); //第二个数组在第一个数组中不同的项
}
Where art thou
写一个 function,它遍历一个对象数组(第一个参数)并返回一个包含相匹配的属性-值对(第二个参数)的所有对象的数组。如果返回的数组中包含 source 对象的属性-值对,那么此对象的每一个属性-值对都必须存在于 collection 的对象中。
例如,如果第一个参数是 [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }]
,第二个参数是 { last: "Capulet" }
,那么你必须从数组(第一个参数)返回其中的第三个对象,因为它包含了作为第二个参数传递的属性-值对。
function where(collection, source) {
var arr = [];
var keys = Object.keys(source);
arr = collection.filter(function(item){
for (var i = 0; i < keys.length; i++) {
if ( !item.hasOwnProperty(keys[i]) || item[keys[i]] !== source[keys[i]]) {
return false;
}
}
return true;
});
return arr;
}
where([{ first: "Romeo", last: "Montague" },
{ first: "Mercutio", last: null },
{ first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
Pig Latin
把一个英文单词的第一个辅音或辅音丛(consonant cluster)移到词尾,然后加上后缀 "ay"。如果单词以元音开始,你只需要在词尾添加 "way" 就可以了。
function translate(str) {
var temp=[];
var answer;
temp=str.split('');//将str分解为单个字符存入数组
var i=0;
while(temp[i]!='a'&&temp[i]!='o'&&temp[i]!='i'&&temp[i]!='e'&&temp[i]!='u'){
i++;//如果不是元音i++,如果是元音推出循环
}
answer=str.substr(i);//将str不是元音的部分提出
answer+=str.substr(0,i);//将str的元音部分加在answer之后
if(i===0){
answer+="way";//首字母为元音加 way
}else{
answer+="ay";//不是加 ay
}
return answer;
}
translate("consonant");
Missing letters
从传递进来的字母序列中找到缺失的字母并返回它。所有字母都在序列中,返回 undefined。
function fearNotLetter(str) {
for(var i=0,len=str.length;i<len;i++){
var cha = str.charCodeAt(i+1)-str.charCodeAt(i);
if(cha>1){
return String.fromCharCode(str.charCodeAt(i)+1);
}
}
return undefined;
}
fearNotLetter("abce");
Sorted Union
写一个 function,传入两个或两个以上的数组,返回一个以给定的原始数组排序的不包含重复值的新数组。换句话说,所有数组中的所有值都应该以原始顺序被包含在内,但是在最终的数组中不包含重复值。非重复的数字应该以它们原始的顺序排序,但最终的数组不应该以数字顺序排序。
unite([1, 3, 2], [5, 2, 1, 4], [2, 1])
应该返回 [1, 3, 2, 5, 4]
。
unite([1, 3, 2], [1, [5]], [2, [4]])
应该返回 [1, 3, 2, [5], [4]]
。
function unite(arr1, arr2, arr3) {
var arr=[];
//unite中参数总数目(即数组个数)
var len=arguments.length;
//控制遍历哪个数组(arguments[i],i可取0~len-1)
var i=0;
while(i<len){
//控制遍历的数组arguments[i]中元素下标
var j=0;
while(j<arguments[i].length){
//如果arr中没有索引为i的数组参数中的索引为j的元素
//将其push到arr中
if(arr.indexOf(arguments[i][j])==-1)
arr.push(arguments[i][j]);
j++;
}
i++;
}
return arr;
}
unite([1, 3, 2], [5, 2, 1, 4], [2, 1]);
Spinal Tap Case
将字符串转换为 spinal case。Spinal case 是 all-lowercase-words-joined-by-dashes 这种形式的,也就是以连字符连接所有小写单词。
spinalCase("This Is Spinal Tap")
应该返回 "this-is-spinal-tap"
。
spinalCase("thisIsSpinalTap")
应该返回 "this-is-spinal-tap"
。
function spinalCase(str) {
return str.split(/\s|_|(?=[A-Z])/).join('-').toLowerCase();
}
spinalCase('ThisIsSpinalTap');
// 方法2
function spinalCase(str) {
// Create a variable for the white space and underscores.
var regex = /\s+|_+/g;
// Replace low-upper case to low-space-uppercase
str = str.replace(/([a-z])([A-Z])/g, '$1 $2');
// Replace space and underscore with -
return str.replace(regex, '-').toLowerCase();
}
Sum All Odd Fibonacci Numbers
给一个正整数num
,返回小于或等于num
的斐波纳契奇数之和。斐波纳契数列中的前几个数字是 1、1、2、3、5 和 8,随后的每一个数字都是前两个数字之和。
function sumFibs(num) {
if(num < 0) {
return undefined;
}
var sumOdds = 0; // Sum of all odd fib numbers
for(var n1 = 0, n2 = 1, temp; n2 <= num; temp = n2, n2 += n1, n1 = temp) {
sumOdds += n2 * (n2 % 2);
}
return sumOdds;
}
sumFibs(4);
// ---------
function sumFibs(num) {
var prevNumber = 0;
var currNumber = 1;
var result = 0;
while (currNumber <= num) {
if (currNumber % 2 !== 0) {
result += currNumber;
}
currNumber += prevNumber;
prevNumber = currNumber - prevNumber;
}
return result;
}
Finders Keepers
写一个 function
,它遍历数组 arr
,并返回数组中第一个满足 func
返回值的元素。举个例子,如果 arr
为 [1, 2, 3]
,func
为 function(num) {return num === 2; }
,那么 find
的返回值应为 2
。
function find(arr, func) {
filterArr = arr.filter(func); //filter array with the function provided
return filterArr[0];
}
find([1, 2, 3, 4], function(num){ return num % 2 === 0; });
Drop it
让我们来丢弃数组(arr)的元素,从左边开始,直到回调函数return true就停止。
第二个参数,func
,是一个函数。用来测试数组的第一个元素,如果返回fasle,就从数组中抛出该元素(注意:此时数组已被改变),继续测试数组的第一个元素,如果返回fasle,继续抛出,直到返回true。
最后返回数组的剩余部分,如果没有剩余,就返回一个空数组。
function drop(arr, func) {
// drop them elements.
var times = arr.length;
for (var i = 0; i < times; i++) {
if (func(arr[0])) {
break;
} else {
arr.shift();
}
}
return arr;
}
drop([1, 2, 3], function(n) {return n < 3; });
// 方法2
function drop(arr, func) {
return arr.slice(arr.findIndex(func) >= 0 ? arr.findIndex(func): arr.length, arr.length);
}
// 方法3
function drop(arr, func) {
while(arr.length > 0 && !func(arr[0])) {
arr.shift();
}
return arr;
}
Steamroller
对嵌套的数组进行扁平化处理。你必须考虑到不同层级的嵌套。
steamroller([[["a"]], [["b"]]])
应该返回 ["a", "b"]
。
steamroller([1, [2], [3, [[4]]]])
应该返回 [1, 2, 3, 4]
。
function steamroller(arr) {
var flattenedArray = [];
// Create function that adds an element if it is not an array.
// If it is an array, then loops through it and uses recursion on that array.
var flatten = function(arg) {
if (!Array.isArray(arg)) {
flattenedArray.push(arg);
} else {
for (var a in arg) {
flatten(arg[a]);
}
}
};
// Call the function for each element in the array
arr.forEach(flatten);
return flattenedArray;
}
steamroller([1, [2], [3, [[4]]]]);
// 方法2
function steamroller(arr) {
return arr.toString()
.replace(',,', ',') // "1,2,,3" => "1,2,3"
.split(',') // ['1','2','3']
.map(function(v) {
if (v == '[object Object]') { // bring back empty objects
return {};
} else if (isNaN(v)) { // if not a number (string)
return v;
} else {
return parseInt(v); // if a number in a string, convert it
}
});
}
Everything Be True
完善编辑器中的every函数,如果集合(collection)中的所有对象都存在对应的属性(pre),并且属性(pre)对应的值为真。函数返回ture。反之,返回false。
function every(collection, pre) {
// Is everyone being true?
return collection.every(obj => obj[pre]);
}
every([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"},
{"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex");
// 方法2
function every(collection, pre) {
return collection.every(function (element) {
return element.hasOwnProperty(pre) && Boolean(element[pre]);
});
}
// 方法3
function every(collection, pre) {
// Create a counter to check how many are true.
var counter = 0;
// Check for each object
for (var c in collection) {
// If it is has property and value is truthy
if (collection[c].hasOwnProperty(pre) && Boolean(collection[c][pre])) {
counter++;
}
}
// Outside the loop, check to see if we got true for all of them and return true or false
return counter == collection.length;
}
Arguments Optional
创建一个计算两个参数之和的 function。如果只有一个参数,则返回一个 function,该 function 请求一个参数然后返回求和的结果。
例如,add(2, 3)
应该返回 5
,而 add(2)
应该返回一个 function。
function add() {
// Function to check if a number is actually a number
// and return undefined otherwise.
var checkNum = function(num) {
if (typeof num !== 'number') {
return undefined;
} else
return num;
};
// Check if we have two parameters, check if they are numbers
// handle the case where one is not
// returns the addition.
if (arguments.length > 1) {
var a = checkNum(arguments[0]);
var b = checkNum(arguments[1]);
if (a === undefined || b === undefined) {
return undefined;
} else {
return a + b;
}
} else {
// If only one parameter was found, returns a new function that expects two
// Store first argument before entering the new function scope
var c = arguments[0];
// Check the number again, must be outside the function to about returning an object
// instead of undefined.
if (checkNum(c)) {
// Return function that expect a second argument.
return function(arg2) {
// Check for non-numbers
if (c === undefined || checkNum(arg2) === undefined) {
return undefined;
} else {
// if numbers then add them.
return c + arg2;
}
};
}
}
}
add(2,3);
// 方法2
function add() {
var args = Array.from(arguments);
return args.some(n => typeof n !== 'number') ?
undefined:
args.length > 1 ?
args.reduce((acc, n) => acc += n, 0):
(n) => typeof n === "number" ?
n + args[0]:
undefined;
}